AzeorthCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionList *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet. More...
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::list<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
613 :
614 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
615 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
617{
619 m_skipCheck = skipCheck;
620 m_selfContainer = nullptr;
622 m_executedCurrently = false;
625 m_comboTarget = nullptr;
626 m_delayStart = 0;
628
630 m_auraScaleMask = 0;
631 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
632
633 // Get data for type of attack
634 switch (m_spellInfo->DmgClass)
635 {
639 else
641 break;
644 break;
645 default:
646 // Wands
649 else
651 break;
652 }
653
654 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
655
657 // wand case
660 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
661
662 if (originalCasterGUID)
663 m_originalCasterGUID = originalCasterGUID;
664 else
666
669 else
670 {
673 m_originalCaster = nullptr;
674 }
675
677 _triggeredCastFlags = triggerFlags;
678 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
680
681 m_CastItem = nullptr;
682
683 unitTarget = nullptr;
684 itemTarget = nullptr;
685 gameObjTarget = nullptr;
686 destTarget = nullptr;
687 damage = 0;
691 m_damage = 0;
692 m_healing = 0;
693 m_procAttacker = 0;
694 m_procVictim = 0;
695 m_procEx = 0;
696 focusObject = nullptr;
697 m_cast_count = 0;
698 m_glyphIndex = 0;
699 m_preCastSpell = 0;
700 m_spellAura = nullptr;
701 _scriptsLoaded = false;
702
703 //Auto Shot & Shoot (wand)
705
706 m_runesState = 0;
707 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
708 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
709 m_timer = 0; // will set to castime in prepare
710 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
711 m_immediateHandled = false;
712
714
716
717 // Determine if spell can be reflected back to the caster
718 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
722
724 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
725
726 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
728
729 // xinef:
730 _spellTargetsSelected = false;
731
732 m_weaponItem = nullptr;
733}
std::uint8_t uint8
Definition: Define.h:110
std::uint32_t uint32
Definition: Define.h:108
@ TYPEID_PLAYER
Definition: ObjectGuid.h:38
@ OFF_ATTACK
Definition: Unit.h:397
@ BASE_ATTACK
Definition: Unit.h:396
@ RANGED_ATTACK
Definition: Unit.h:398
@ DIMINISHING_LEVEL_1
Definition: Unit.h:694
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:233
@ SPELL_FLAG_NORMAL
Definition: Spell.h:81
@ SPELL_STATE_NULL
Definition: Spell.h:223
TriggerCastFlags
Definition: SpellDefines.h:130
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:139
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition: SpellDefines.h:137
#define sSpellMgr
Definition: SpellMgr.h:803
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1596
@ DIMINISHING_NONE
Definition: SharedDefines.h:3230
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:788
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:146
@ SPELL_ATTR2_AUTO_REPEAT
Definition: SharedDefines.h:433
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:398
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition: SharedDefines.h:489
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1520
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1518
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1519
@ SPELL_CUSTOM_ERROR_NONE
Definition: SharedDefines.h:1115
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:358
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:383
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:509
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition: SharedDefines.h:594
SpellSchoolMask
Definition: SharedDefines.h:267
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:204
Definition: Item.h:214
Player * ToPlayer()
Definition: Object.h:195
bool IsInWorld() const
Definition: Object.h:101
TypeID GetTypeId() const
Definition: Object.h:121
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:521
Unit * GetCharmerOrOwner() const
Definition: Unit.h:2063
uint32 getClassMask() const
Definition: Unit.h:1425
Definition: Spell.h:94
Definition: Spell.h:211
Unit * m_comboTarget
Definition: Spell.h:542
int8 m_comboPointGain
Definition: Spell.h:543
GameObject * gameObjTarget
Definition: Spell.h:652
bool m_referencedFromCurrentSpell
Definition: Spell.h:643
bool m_canReflect
Definition: Spell.h:619
uint32 m_procVictim
Definition: Spell.h:674
Unit * m_originalCaster
Definition: Spell.h:607
bool m_needComboPoints
Definition: Spell.h:645
uint64 m_delayStart
Definition: Spell.h:637
bool _scriptsLoaded
Definition: Spell.h:725
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:766
int32 damage
Definition: Spell.h:654
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:655
int32 m_channeledDuration
Definition: Spell.h:618
Aura * m_spellAura
Definition: Spell.h:657
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:700
Unit *const m_caster
Definition: Spell.h:601
uint8 m_delayAtDamageCount
Definition: Spell.h:626
WeaponAttackType m_attackType
Definition: Spell.h:615
bool m_immediateHandled
Definition: Spell.h:640
uint32 m_spellState
Definition: Spell.h:762
ObjectGuid m_originalCasterGUID
Definition: Spell.h:605
void CleanupTargetList()
Definition: Spell.cpp:2408
int32 m_timer
Definition: Spell.h:763
int32 m_casttime
Definition: Spell.h:617
Item * itemTarget
Definition: Spell.h:651
uint8 m_cast_count
Definition: Spell.h:524
int32 m_damage
Definition: Spell.h:667
bool m_executedCurrently
Definition: Spell.h:644
DiminishingLevels m_diminishLevel
Definition: Spell.h:660
float m_damageMultipliers[3]
Definition: Spell.h:647
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:780
uint8 m_auraScaleMask
Definition: Spell.h:774
SpellCustomErrors m_customError
Definition: Spell.h:528
uint8 m_spellFlags
Definition: Spell.h:621
bool m_skipCheck
Definition: Spell.h:773
int32 m_healing
Definition: Spell.h:668
uint32 m_glyphIndex
Definition: Spell.h:525
uint8 m_channelTargetEffectMask
Definition: Spell.h:682
Item * m_weaponItem
Definition: Spell.h:522
Unit * unitTarget
Definition: Spell.h:650
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:614
SpellEvent * _spellEvent
Definition: Spell.h:765
bool _spellTargetsSelected
Definition: Spell.h:778
uint32 m_preCastSpell
Definition: Spell.h:526
WorldLocation * destTarget
Definition: Spell.h:653
Spell ** m_selfContainer
Definition: Spell.h:609
uint8 m_applyMultiplierMask
Definition: Spell.h:646
DiminishingGroup m_diminishGroup
Definition: Spell.h:661
uint32 m_procEx
Definition: Spell.h:675
Item * m_CastItem
Definition: Spell.h:521
SpellValue *const m_spellValue
Definition: Spell.h:603
int32 m_powerCost
Definition: Spell.h:616
uint32 m_procAttacker
Definition: Spell.h:673
GameObject * focusObject
Definition: Spell.h:664
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
uint8 m_runesState
Definition: Spell.h:624
bool m_autoRepeat
Definition: Spell.h:623
bool IsPassive() const
Definition: SpellInfo.cpp:1081
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1249
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:412
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:868
bool IsPositive() const
Definition: SpellInfo.cpp:1220
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1266
uint32 DmgClass
Definition: SpellInfo.h:387
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1259
Definition: ByteBuffer.h:70

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TYPEID_PLAYER, and unitTarget.

◆ ~Spell()

Spell::~Spell ( )
736{
737 // unload scripts
738 while (!m_loadedScripts.empty())
739 {
740 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
741 (*itr)->_Unload();
742 delete (*itr);
743 m_loadedScripts.erase(itr);
744 }
745
747 {
748 // Clean the reference to avoid later crash.
749 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
750 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
751 *m_selfContainer = nullptr;
752 }
753
754 delete m_spellValue;
755
757}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
void CheckEffectExecuteData()
Definition: Spell.cpp:8490
std::list< SpellScript * > m_loadedScripts
Definition: Spell.h:740
uint32 Id
Definition: SpellInfo.h:318

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3823{
3824 // update pointers base at GUIDs to prevent access to non-existed already object
3825 if (!UpdatePointers())
3826 {
3827 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3828 cancel();
3829 return;
3830 }
3831
3832 // cancel at lost explicit target during cast
3834 {
3835 cancel();
3836 return;
3837 }
3838
3839 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3841 {
3843 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3845
3846 if (Unit* charm = m_caster->GetCharm())
3847 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3848 }
3849
3850 if (Player* playerCaster = m_caster->ToPlayer())
3851 {
3852 // now that we've done the basic check, now run the scripts
3853 // should be done before the spell is actually executed
3854 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3855
3856 // As of 3.0.2 pets begin attacking their owner's target immediately
3857 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3858 // This prevents spells such as Hunter's Mark from triggering pet attack
3859 // xinef: take into account SPELL_ATTR3_SUPRESS_TARGET_PROCS
3861 if (!playerCaster->m_Controlled.empty())
3862 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3863 if (Unit* pet = *itr)
3864 if (pet->IsAlive() && pet->GetTypeId() == TYPEID_UNIT)
3865 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3866 }
3867
3869
3873
3875
3876 Player* modOwner = m_caster->GetSpellModOwner();
3877 // skip check if done already (for instant cast spells for example)
3878 if (!skipCheck)
3879 {
3880 SpellCastResult castResult = CheckCast(false);
3881 if (castResult != SPELL_CAST_OK)
3882 {
3883 SendCastResult(castResult);
3884 SendInterrupted(0);
3885
3886 finish(false);
3887 SetExecutedCurrently(false);
3888 return;
3889 }
3890
3891 // additional check after cast bar completes (must not be in CheckCast)
3892 // if trade not complete then remember it in trade data
3894 {
3896 {
3897 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3898 {
3899 if (!my_trade->IsInAcceptProcess())
3900 {
3901 // Spell will be casted at completing the trade. Silently ignore at this place
3902 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3904 SendInterrupted(0);
3905
3906 finish(false);
3907 SetExecutedCurrently(false);
3908 return;
3909 }
3910 }
3911 }
3912 }
3913 }
3914
3915 if (modOwner)
3916 modOwner->SetSpellModTakingSpell(this, true);
3917
3920
3921 if (modOwner)
3922 modOwner->SetSpellModTakingSpell(this, false);
3923
3924 // Spell may be finished after target map check
3926 {
3927 SendInterrupted(0);
3928 finish(false);
3929 SetExecutedCurrently(false);
3930 return;
3931 }
3932
3933 if (modOwner)
3934 modOwner->SetSpellModTakingSpell(this, true);
3935
3937
3939
3940 if (modOwner)
3941 modOwner->SetSpellModTakingSpell(this, false);
3942
3943 // traded items have trade slot instead of guid in m_itemTargetGUID
3944 // set to real guid to be sent later to the client
3946
3948 {
3950 {
3953 }
3954
3956 }
3957
3959 {
3960 // Powers have to be taken before SendSpellGo
3961 TakePower();
3962 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3963 }
3964 else if (Item* targetItem = m_targets.GetItemTarget())
3965 {
3967 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3968 TakeReagents();
3969 }
3970
3972
3973 // CAST SPELL
3974 if (modOwner)
3975 modOwner->SetSpellModTakingSpell(this, true);
3976
3978
3980
3981 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3982 SendSpellGo();
3983
3984 if (modOwner)
3985 modOwner->SetSpellModTakingSpell(this, false);
3986
3987 if (m_originalCaster)
3988 {
3989 // Handle procs on cast
3990 uint32 procAttacker = m_procAttacker;
3991 if (!procAttacker)
3992 {
3993 bool IsPositive = m_spellInfo->IsPositive();
3995 {
3997 }
3998 else
3999 {
4001 }
4002 }
4003
4004 uint32 procEx = PROC_EX_NORMAL_HIT;
4005
4006 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4007 {
4008 if (ihit->missCondition != SPELL_MISS_NONE)
4009 {
4010 continue;
4011 }
4012
4013 if (!ihit->crit)
4014 {
4015 continue;
4016 }
4017
4018 procEx |= PROC_EX_CRITICAL_HIT;
4019 break;
4020 }
4021
4024 }
4025
4026 if (modOwner)
4027 modOwner->SetSpellModTakingSpell(this, true);
4028
4030 if (resetAttackTimers)
4031 {
4033 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4034 {
4035 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4036 {
4037 resetAttackTimers = false;
4038 break;
4039 }
4040 }
4041 }
4042
4043 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4044 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4045 {
4046 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4047 // in case delayed spell remove item at cast delay start
4048 TakeCastItem();
4049
4050 // Okay, maps created, now prepare flags
4051 m_immediateHandled = false;
4053 SetDelayStart(0);
4054
4057
4058 // remove all applied mods at this point
4059 // dont allow user to use them twice in case spell did not reach current target
4060 if (modOwner)
4061 modOwner->RemoveSpellMods(this);
4062
4063 // Xinef: why do we keep focus after spell is sent to air?
4064 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4065 // Xinef: we get focused to it out of nowhere...
4066 if (Creature* creatureCaster = m_caster->ToCreature())
4067 creatureCaster->ReleaseFocus(this);
4068 }
4069 else
4070 {
4071 // Immediate spell, no big deal
4073 }
4074
4075 if (resetAttackTimers)
4076 {
4077 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4078 {
4079 resetAttackTimers = false;
4080 }
4081
4082 if (resetAttackTimers)
4083 {
4085
4087 {
4089 }
4090
4092 }
4093 }
4094
4096
4097 if (modOwner)
4098 modOwner->SetSpellModTakingSpell(this, false);
4099
4100 if (const std::vector<int32>* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4101 {
4102 for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
4103 if (*i < 0)
4105 else
4107 }
4108
4109 // Interrupt Spell casting
4110 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4112 if (Unit* target = m_targets.GetUnitTarget())
4113 if (target->GetTypeId() == TYPEID_UNIT)
4114 m_caster->CastSpell(target, 32747, true);
4115
4116 // xinef: start combat at cast for delayed spells, only for explicit target
4117 if (Unit* target = m_targets.GetUnitTarget())
4120 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4121
4125
4126 SetExecutedCurrently(false);
4127}
@ TYPEID_UNIT
Definition: ObjectGuid.h:37
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
@ CHEAT_COOLDOWN
Definition: Player.h:993
@ UNIT_STATE_CASTING
Definition: Unit.h:340
#define sScriptMgr
Definition: ScriptMgr.h:2690
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition: SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ SPELL_STATE_DELAYED
Definition: Spell.h:228
@ SPELL_STATE_FINISHED
Definition: Spell.h:226
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:134
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition: SpellDefines.h:135
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition: SpellDefines.h:141
@ TARGET_FLAG_TRADE_ITEM
Definition: SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition: SpellInfo.h:47
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition: SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:125
@ PROC_FLAG_NONE
Definition: SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:131
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:121
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:161
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:149
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:624
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:806
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:445
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition: SharedDefines.h:391
@ SPELL_ATTR3_SUPRESS_TARGET_PROCS
Definition: SharedDefines.h:482
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1517
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1491
SpellCastResult
Definition: SharedDefines.h:920
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:948
@ SPELL_CAST_OK
Definition: SharedDefines.h:1110
Definition: Creature.h:46
uint32 GetEntry() const
Definition: Object.h:109
Creature * ToCreature()
Definition: Object.h:197
Definition: Pet.h:40
Definition: Player.h:1046
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2125
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:9809
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13613
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:9743
Pet * GetPet() const
Definition: Player.cpp:8766
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1154
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:8917
TradeData * GetTradeData() const
Definition: Player.h:1344
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3456
Definition: TradeData.h:36
Definition: Unit.h:1290
void ClearUnitState(uint32 f)
Definition: Unit.h:1399
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:2211
Unit * GetCharm() const
Definition: Unit.cpp:11470
Player * GetSpellModOwner() const
Definition: Unit.cpp:17537
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:14456
bool haveOffhandWeapon() const
Definition: Unit.cpp:670
bool IsPet() const
Definition: Unit.h:1413
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4616
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1428
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:5624
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition: Unit.cpp:7134
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1398
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:11058
bool IsControlledByPlayer() const
Definition: Unit.h:2044
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:1306
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:21469
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:826
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:357
void UpdateTradeSlotItem()
Definition: Spell.cpp:394
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:362
Item * GetItemTarget() const
Definition: Spell.h:139
uint32 GetTargetMask() const
Definition: Spell.h:117
Unit * GetUnitTarget() const
Get Unit Target.
Definition: Spell.cpp:258
int8 effectIndex
Definition: Spell.h:279
SpellInfo const * spellInfo
Definition: Spell.h:278
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:574
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8544
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8751
SpellCastTargets m_targets
Definition: Spell.h:527
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:771
void handle_immediate()
Definition: Spell.cpp:4129
void SendSpellGo()
Definition: Spell.cpp:4799
void TakeReagents()
Definition: Spell.cpp:5533
void SetExecutedCurrently(bool yes)
Definition: Spell.h:560
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5176
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8576
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8531
void cancel(bool bySelf=false)
Definition: Spell.cpp:3733
void SendSpellCooldown()
Definition: Spell.cpp:4366
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8518
void HandleLaunchPhase()
Definition: Spell.cpp:8231
bool UpdatePointers()
Definition: Spell.cpp:7864
void SetDelayStart(uint64 m_time)
Definition: Spell.h:562
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:681
void SelectSpellTargets()
Definition: Spell.cpp:861
void TakePower()
Definition: Spell.cpp:5317
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5652
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4671
uint64 GetDelayMoment() const
Definition: Spell.h:563
void TakeCastItem()
Definition: Spell.cpp:5254
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8078
void finish(bool ok=true)
Definition: Spell.cpp:4489
float Speed
Definition: SpellInfo.h:368
bool IsChanneled() const
Definition: SpellInfo.cpp:1239
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2332
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:876

References _spellTargetsSelected, _triggeredCastFlags, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), Unit::HasUnitState(), Unit::haveOffhandWeapon(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, TYPEID_PLAYER, TYPEID_UNIT, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4292{
4293 // Take for real after all targets are processed
4295 {
4297 }
4298
4299 // Real add combo points from effects
4301 {
4302 // remove Premed-like effects unless they were caused by ourselves
4303 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4305 {
4307 }
4308
4310 }
4311
4313 {
4315 }
4316
4319 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4320 {
4321 // Xinef: Properly clear infinite cooldowns in some cases
4322 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4325 }
4326
4327 // Handle procs on finish
4328 if (m_originalCaster)
4329 {
4330 uint32 procAttacker = m_procAttacker;
4331 if (!procAttacker)
4332 {
4333 bool IsPositive = m_spellInfo->IsPositive();
4335 {
4337 }
4338 else
4339 {
4341 }
4342 }
4343
4344 uint32 procEx = PROC_EX_NORMAL_HIT;
4345 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4346 {
4347 if (ihit->missCondition != SPELL_MISS_NONE)
4348 {
4349 continue;
4350 }
4351
4352 if (!ihit->crit)
4353 {
4354 continue;
4355 }
4356
4357 procEx |= PROC_EX_CRITICAL_HIT;
4358 break;
4359 }
4360
4363 }
4364}
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition: SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition: SpellMgr.h:245
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition: SharedDefines.h:769
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:10850
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:1589
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:11420
void ClearComboPoints()
Definition: Unit.cpp:17781
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:17755
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5843
bool IsAutoRepeat() const
Definition: Spell.h:548
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8068
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1195

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), Object::GetTypeId(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4264{
4265 m_spellAura = nullptr;
4266 // initialize Diminishing Returns Data
4269
4270 // handle some immediate features of the spell here
4272
4274
4275 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4276 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4277 {
4278 // don't do anything for empty effect
4279 if (!m_spellInfo->Effects[j].IsEffect())
4280 continue;
4281
4282 // call effect handlers to handle destination hit
4283 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4284 }
4285
4286 // process items
4287 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4288 DoAllEffectOnTarget(&(*ihit));
4289}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:235
void HandleThreatSpells()
Definition: Spell.cpp:5582
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5629
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:698
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2646
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:391

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
531 {
532 if (target != m_comboTarget)
533 {
534 m_comboTarget = target;
535 m_comboPointGain = amount;
536 }
537 else
538 {
539 m_comboPointGain += amount;
540 }
541 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2642{
2643 m_destTargets[effIndex] = dest;
2644}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2551{
2552 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2553 {
2554 if (!m_spellInfo->Effects[effIndex].IsEffect())
2555 effectMask &= ~(1 << effIndex);
2556 else
2557 {
2558 switch (m_spellInfo->Effects[effIndex].Effect)
2559 {
2563 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2564 effectMask &= ~(1 << effIndex);
2565 break;
2566 default:
2567 break;
2568 }
2569 }
2570 }
2571
2572 if (!effectMask)
2573 return;
2574
2575 ObjectGuid targetGUID = go->GetGUID();
2576
2577 // Lookup target in already in list
2578 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2579 {
2580 if (targetGUID == ihit->targetGUID) // Found in list
2581 {
2582 ihit->effectMask |= effectMask; // Add only effect mask
2583 return;
2584 }
2585 }
2586
2587 // This is new target calculate data for him
2588
2589 GOTargetInfo target;
2590 target.targetGUID = targetGUID;
2591 target.effectMask = effectMask;
2592 target.processed = false; // Effects not apply on target
2593
2594 // Spell have speed - need calculate incoming time
2595 if (m_spellInfo->Speed > 0.0f)
2596 {
2597 // calculate spell incoming interval
2598 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2599 if (dist < 5.0f)
2600 dist = 5.0f;
2601 target.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
2602 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2603 m_delayMoment = target.timeDelay;
2604 }
2605 else
2606 target.timeDelay = 0LL;
2607
2608 // Add target to list
2609 m_UniqueGOTargetInfo.push_back(target);
2610}
std::uint64_t uint64
Definition: Define.h:107
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition: SharedDefines.h:1565
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition: SharedDefines.h:838
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition: SharedDefines.h:839
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition: SharedDefines.h:837
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1247
Definition: ObjectGuid.h:120
uint64 m_delayMoment
Definition: Spell.h:638
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:691

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2613{
2614 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2615 if (!m_spellInfo->Effects[effIndex].IsEffect())
2616 effectMask &= ~(1 << effIndex);
2617
2618 // no effects left
2619 if (!effectMask)
2620 return;
2621
2622 // Lookup target in already in list
2623 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2624 {
2625 if (item == ihit->item) // Found in list
2626 {
2627 ihit->effectMask |= effectMask; // Add only effect mask
2628 return;
2629 }
2630 }
2631
2632 // This is new target add data
2633
2634 ItemTargetInfo target;
2635 target.item = item;
2636 target.effectMask = effectMask;
2637
2638 m_UniqueItemInfo.push_back(target);
2639}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2418{
2419 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2420 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2421 effectMask &= ~(1 << effIndex);
2422
2423 // no effects left
2424 if (!effectMask)
2425 return;
2426
2427 if (checkIfValid)
2428 {
2429 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2430 if (res != SPELL_CAST_OK)
2431 return;
2432 }
2433
2434 // Check for effect immune skip if immuned
2435 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2436 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2437 effectMask &= ~(1 << effIndex);
2438
2439 ObjectGuid targetGUID = target->GetGUID();
2440
2441 // Lookup target in already in list
2442 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2443 {
2444 if (targetGUID == ihit->targetGUID) // Found in list
2445 {
2446 ihit->effectMask |= effectMask; // Immune effects removed from mask
2447 ihit->scaleAura = false;
2448 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2449 {
2450 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2451 if (uint32(target->getLevel() + 10) >= auraSpell->SpellLevel)
2452 ihit->scaleAura = true;
2453 }
2454
2455 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2456 return;
2457 }
2458 }
2459
2460 // This is new target calculate data for him
2461
2462 // Get spell hit result on target
2463 TargetInfo targetInfo;
2464 targetInfo.targetGUID = targetGUID; // Store target GUID
2465 targetInfo.effectMask = effectMask; // Store all effects not immune
2466 targetInfo.processed = false; // Effects not apply on target
2467 targetInfo.alive = target->IsAlive();
2468 targetInfo.damage = 0;
2469 targetInfo.crit = false;
2470 targetInfo.scaleAura = false;
2471 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2472 {
2473 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2474 if (uint32(target->getLevel() + 10) >= auraSpell->SpellLevel)
2475 targetInfo.scaleAura = true;
2476 }
2477
2478 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2479
2480 // Calculate hit result
2481 if (m_originalCaster)
2482 {
2483 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2484 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2485 {
2486 targetInfo.missCondition = SPELL_MISS_NONE;
2487 }
2488 }
2489 else
2490 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2491
2492 // Spell have speed - need calculate incoming time
2493 // Incoming time is zero for self casts. At least I think so.
2494 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2495 {
2496 // calculate spell incoming interval
2498 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2499
2500 if (dist < 5.0f)
2501 dist = 5.0f;
2502 targetInfo.timeDelay = (uint64) floor(dist / m_spellInfo->Speed * 1000.0f);
2503
2504 // Calculate minimum incoming time
2505 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2506 m_delayMoment = targetInfo.timeDelay;
2507 }
2508 else
2509 targetInfo.timeDelay = 0LL;
2510
2511 // If target reflect spell back to caster
2512 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2513 {
2514 // Calculate reflected spell result on caster
2516
2517 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2518 targetInfo.reflectResult = SPELL_MISS_PARRY;
2519
2520 // Increase time interval for reflected spells by 1.5
2522 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2523
2525
2526 // HACK: workaround check for succubus seduction case
2528 if (m_caster->IsPet())
2529 {
2530 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2531 switch (ci->family)
2532 {
2534 {
2535 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2536 cancel();
2537 }
2538 break;
2539 return;
2540 }
2541 }
2542 }
2543 else
2544 targetInfo.reflectResult = SPELL_MISS_NONE;
2545
2546 // Add target to list
2547 m_UniqueTargetInfo.push_back(targetInfo);
2548}
#define sObjectMgr
Definition: ObjectMgr.h:1612
@ SPELL_FLAG_REFLECTED
Definition: Spell.h:82
@ CREATURE_FAMILY_SUCCUBUS
Definition: SharedDefines.h:2636
@ SPELL_MISS_PARRY
Definition: SharedDefines.h:1495
@ SPELL_MISS_IMMUNE
Definition: SharedDefines.h:1498
@ SPELL_MISS_EVADE
Definition: SharedDefines.h:1497
@ SPELL_MISS_REFLECT
Definition: SharedDefines.h:1502
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.cpp:114
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:136
Definition: CreatureData.h:176
uint32 family
Definition: CreatureData.h:210
float GetPositionZ() const
Definition: Position.h:119
float GetPositionX() const
Definition: Position.h:117
float GetPositionY() const
Definition: Position.h:118
bool IsAlive() const
Definition: Unit.h:2024
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Calculate spell hit result can be: Every spell can: Evade/Immune/Reflect/Sucesful hit For melee based...
Definition: Unit.cpp:3923
EventProcessor m_Events
Definition: Unit.h:2344
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition: Unit.cpp:13766
uint8 getLevel() const
Definition: Unit.h:1418
Definition: Spell.h:254
bool processed
Definition: Spell.h:260
int32 damage
Definition: Spell.h:264
SpellMissInfo missCondition
Definition: Spell.h:257
bool scaleAura
Definition: Spell.h:263
bool crit
Definition: Spell.h:262
uint64 timeDelay
Definition: Spell.h:256
ObjectGuid targetGUID
Definition: Spell.h:255
SpellMissInfo reflectResult
Definition: Spell.h:258
bool alive
Definition: Spell.h:261
uint8 effectMask
Definition: Spell.h:259
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition: Spell.cpp:7926
Definition: Spell.h:845
Definition: SpellInfo.h:314
uint32 SpellLevel
Definition: SpellInfo.h:358
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2481
uint32 SpellIconID
Definition: SpellInfo.h:378
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:1743

References EventProcessor::AddEvent(), TargetInfo::alive, EventProcessor::CalculateTime(), cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::getLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, Unit::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
942{
943 if (m_targets.HasDst())
944 {
945 if (m_targets.HasTraj())
946 {
947 float speed = m_targets.GetSpeedXY();
948 if (speed > 0.0f)
949 return (uint64)floor(m_targets.GetDist2d() / speed * 1000.0f);
950 }
951 else if (m_spellInfo->Speed > 0.0f)
952 {
953 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
954 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
955 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
956 }
957 }
958
959 return 0;
960}
float GetExactDist(float x, float y, float z) const
Definition: Position.h:178
bool HasTraj() const
Definition: Spell.h:166
bool HasDst() const
Definition: Spell.h:165
float GetSpeedXY() const
Definition: Spell.h:174
float GetDist2d() const
Definition: Spell.h:173
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:447

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1180{
1181 if (m_spellInfo->Effects[i].MiscValue)
1182 speedZ = float(m_spellInfo->Effects[i].MiscValue) / 10;
1183 else if (m_spellInfo->Effects[i].MiscValueB)
1184 speedZ = float(m_spellInfo->Effects[i].MiscValueB) / 10;
1185 else
1186 speedZ = 10.0f;
1187 speedXY = dist * 10.0f / speedZ;
1188}

References SpellInfo::Effects, and m_spellInfo.

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition: Unit.cpp:15564
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: Spell.h:213

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8545{
8546 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8547 {
8548 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8549 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8550 for (; hookItr != hookItrEnd; ++hookItr)
8551 (*hookItr).Call(*scritr);
8552
8553 (*scritr)->_FinishScriptCall();
8554 }
8555}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition: SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8657{
8658 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8659 {
8660 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8661 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8662 for (; hookItr != hookItrEnd; ++hookItr)
8663 (*hookItr).Call(*scritr);
8664
8665 (*scritr)->_FinishScriptCall();
8666 }
8667}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition: SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8519{
8520 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8521 {
8522 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8523 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8524 for (; hookItr != hookItrEnd; ++hookItr)
8525 (*hookItr).Call(*scritr);
8526
8527 (*scritr)->_FinishScriptCall();
8528 }
8529}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition: SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8631{
8632 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8633 {
8634 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8635 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8636 for (; hookItr != hookItrEnd; ++hookItr)
8637 (*hookItr).Call(*scritr, missInfo);
8638
8639 (*scritr)->_FinishScriptCall();
8640 }
8641}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition: SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8558{
8560 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8561 {
8562 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8563 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8564 for (; hookItr != hookItrEnd; ++hookItr)
8565 {
8566 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8567 if (retVal == SPELL_CAST_OK)
8568 retVal = tempResult;
8569 }
8570
8571 (*scritr)->_FinishScriptCall();
8572 }
8573 return retVal;
8574}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition: SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8698{
8699 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8700 {
8701 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8702 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8703 for (; hookItr != hookItrEnd; ++hookItr)
8704 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8705 hookItr->Call(*scritr, target);
8706
8707 (*scritr)->_FinishScriptCall();
8708 }
8709}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition: SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8583{
8584 // execute script effect handler hooks and check if effects was prevented
8585 bool preventDefault = false;
8586 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8587 {
8588 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8589 SpellScriptHookType hookType;
8590 switch (mode)
8591 {
8593 effItr = (*scritr)->OnEffectLaunch.begin();
8594 effEndItr = (*scritr)->OnEffectLaunch.end();
8596 break;
8598 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8599 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8601 break;
8603 effItr = (*scritr)->OnEffectHit.begin();
8604 effEndItr = (*scritr)->OnEffectHit.end();
8606 break;
8608 effItr = (*scritr)->OnEffectHitTarget.begin();
8609 effEndItr = (*scritr)->OnEffectHitTarget.end();
8611 break;
8612 default:
8613 ABORT();
8614 return false;
8615 }
8616 (*scritr)->_PrepareScriptCall(hookType);
8617 for (; effItr != effEndItr; ++effItr)
8618 // effect execution can be prevented
8619 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8620 (*effItr).Call(*scritr, effIndex);
8621
8622 if (!preventDefault)
8623 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8624
8625 (*scritr)->_FinishScriptCall();
8626 }
8627 return preventDefault;
8628}
#define ABORT
Definition: Errors.h:76
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition: Spell.h:234
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition: Spell.h:236
SpellScriptHookType
Definition: SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition: SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition: SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition: SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition: SpellScript.h:162

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8670{
8671 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8672 {
8673 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8674 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8675 for (; hookItr != hookItrEnd; ++hookItr)
8676 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8677 hookItr->Call(*scritr, targets);
8678
8679 (*scritr)->_FinishScriptCall();
8680 }
8681}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition: SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8684{
8685 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8686 {
8687 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8688 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8689 for (; hookItr != hookItrEnd; ++hookItr)
8690 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8691 hookItr->Call(*scritr, target);
8692
8693 (*scritr)->_FinishScriptCall();
8694 }
8695}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition: SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8532{
8533 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8534 {
8535 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8536 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8537 for (; hookItr != hookItrEnd; ++hookItr)
8538 (*hookItr).Call(*scritr);
8539
8540 (*scritr)->_FinishScriptCall();
8541 }
8542}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition: SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8644{
8645 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8646 {
8647 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8648 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8649 for (; hookItr != hookItrEnd; ++hookItr)
8650 (*hookItr).Call(*scritr);
8651
8652 (*scritr)->_FinishScriptCall();
8653 }
8654}
@ SPELL_SCRIPT_HOOK_HIT
Definition: SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
7017{
7018 ObjectGuid targetguid = target->GetGUID();
7019
7020 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
7021 {
7023 {
7024 if (m_spellInfo->StackAmount <= 1)
7025 {
7026 if (target->HasAuraEffect(m_spellInfo->Id, j))
7027 return false;
7028 }
7029 else
7030 {
7031 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
7032 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
7033 return false;
7034 }
7035 }
7036 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
7037 {
7038 if (target->HasAuraEffect(m_spellInfo->Id, j))
7039 return false;
7040 }
7041 }
7042
7043 SpellCastResult result = CheckPetCast(target);
7044
7045 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7046 {
7048 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7049 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7050 if (ihit->targetGUID == targetguid)
7051 return true;
7052 }
7053 return false; //target invalid
7054}
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:756
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1055
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:6256
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:6424
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6823
uint32 StackAmount
Definition: SpellInfo.h:369

References CheckPetCast(), SpellInfo::Effects, Unit::GetAuraEffect(), Object::GetGUID(), Unit::HasAuraEffect(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectSpellTargets(), SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellInfo::StackAmount.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
3734{
3736 return;
3737
3738 uint32 oldState = m_spellState;
3739 bool autoRepeat = m_autoRepeat;
3741
3742 m_autoRepeat = false;
3743 switch (oldState)
3744 {
3748 {
3750 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3751 }
3752 [[fallthrough]];
3754 SendInterrupted(0);
3755 // xinef: fixes bugged gcd reset in some cases
3756 if (!autoRepeat)
3758 break;
3759
3761 if (!bySelf)
3762 {
3763 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3764 if ((*ihit).missCondition == SPELL_MISS_NONE)
3765 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3766 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3767
3769 SendInterrupted(0);
3771 }
3772
3774 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3775
3776 // spell is canceled-take mods and clear list
3777 if (Player* player = m_caster->GetSpellModOwner())
3778 player->RemoveSpellMods(this);
3779
3780 m_appliedMods.clear();
3781 break;
3782 default:
3783 break;
3784 }
3785
3787 if (m_selfContainer && *m_selfContainer == this)
3788 *m_selfContainer = nullptr;
3789
3790 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3792 {
3794 }
3795
3796 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3798
3799 //set state back so finish will be processed
3800 m_spellState = oldState;
3801
3802 finish(false);
3803}
@ AURA_REMOVE_BY_CANCEL
Definition: SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition: Spell.h:224
@ SPELL_STATE_CASTING
Definition: Spell.h:225
@ SPELL_EFFECT_ADD_FARSIGHT
Definition: SharedDefines.h:822
@ SPELL_FAILED_INTERRUPTED
Definition: SharedDefines.h:961
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition: ArenaSpectator.h:80
Map * FindMap() const
Definition: Object.h:518
bool NeedSendSpectatorData() const
Definition: Player.cpp:15092
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6953
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6897
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5193
void CancelGlobalCooldown()
Definition: Spell.cpp:8888
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:558
UsedSpellMods m_appliedMods
Definition: Spell.h:545

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetTypeId(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8889{
8891 return;
8892
8893 // Cancel global cooldown when interrupting current cast
8895 return;
8896
8897 // Only players or controlled units have global cooldown
8898 if (m_caster->GetCharmInfo())
8900 else if (m_caster->GetTypeId() == TYPEID_PLAYER)
8902}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:979
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1754
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: Unit.cpp:471
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Unit.h:1127
CharmInfo * GetCharmInfo()
Definition: Unit.h:2099
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:2311
uint32 StartRecoveryTime
Definition: SpellInfo.h:349

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::GetTypeId(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
Todo:
Remove magic numbers
8735{
8737 // Relentless strikes, proc only from first effect
8738 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8739 return effMask & (1 << EFFECT_0);
8740
8741 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8742 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8743 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8744 {
8745 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8746 return true;
8747 }
8748 return effMask;
8749}
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1382
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition: SharedDefines.h:503

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8359{
8360 if (!lockId) // possible case for GO and maybe for items.
8361 return SPELL_CAST_OK;
8362
8363 // Get LockInfo
8364 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8365
8366 if (!lockInfo)
8368
8369 bool reqKey = false; // some locks not have reqs
8370
8371 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8372 {
8373 switch (lockInfo->Type[j])
8374 {
8375 // check key item (many fit cases can be)
8376 case LOCK_KEY_ITEM:
8377 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8378 return SPELL_CAST_OK;
8379 reqKey = true;
8380 break;
8381 // check key skill (only single first fit case can be)
8382 case LOCK_KEY_SKILL:
8383 {
8384 reqKey = true;
8385
8386 // wrong locktype, skip
8387 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8388 continue;
8389
8390 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8391
8392 if (skillId != SKILL_NONE)
8393 {
8394 reqSkillValue = lockInfo->Skill[j];
8395
8396 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8397 skillValue = m_CastItem || m_caster->GetTypeId() != TYPEID_PLAYER ?
8398 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8399
8400 // skill bonus provided by casting spell (mostly item spells)
8401 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8402 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8404 {
8405 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8406 }
8407
8408 if (skillValue < reqSkillValue)
8410 }
8411
8412 return SPELL_CAST_OK;
8413 }
8414 case LOCK_KEY_SPELL:
8415 {
8416 if (m_spellInfo->Id == lockInfo->Index[j])
8417 {
8418 return SPELL_CAST_OK;
8419 }
8420 reqKey = true;
8421 break;
8422 }
8423 }
8424 }
8425
8426 if (reqKey)
8428
8429 return SPELL_CAST_OK;
8430}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition: DBCStructure.h:1288
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition: SharedDefines.h:1402
LockType
Definition: SharedDefines.h:2563
@ LOCK_KEY_ITEM
Definition: SharedDefines.h:2557
@ LOCK_KEY_SKILL
Definition: SharedDefines.h:2558
@ LOCK_KEY_SPELL
Definition: SharedDefines.h:2559
@ SPELL_FAILED_BAD_TARGETS
Definition: SharedDefines.h:933
@ SPELL_FAILED_LOW_CASTLEVEL
Definition: SharedDefines.h:970
SkillType SkillByLockType(LockType locktype)
Definition: SharedDefines.h:2992
@ SKILL_NONE
Definition: SharedDefines.h:2836
@ SKILL_LOCKPICKING
Definition: SharedDefines.h:2947
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5340
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:988
Definition: DBCStructure.h:1291
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1293
uint32 Index[MAX_LOCK_CASE]
Definition: DBCStructure.h:1294
uint32 Skill[MAX_LOCK_CASE]
Definition: DBCStructure.h:1295

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), Object::GetTypeId(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), LockEntry::Type, and TYPEID_PLAYER.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3806{
3807 Player* modOwner = m_caster->GetSpellModOwner();
3808 Spell* lastMod = nullptr;
3809 if (modOwner)
3810 {
3811 lastMod = modOwner->m_spellModTakingSpell;
3812 if (lastMod)
3813 modOwner->SetSpellModTakingSpell(lastMod, false);
3814 }
3815
3816 _cast(skipCheck);
3817
3818 if (lastMod)
3819 modOwner->SetSpellModTakingSpell(lastMod, true);
3820}
Spell * m_spellModTakingSpell
Definition: Player.h:2497
Definition: Spell.h:284
void _cast(bool skipCheck)
Definition: Spell.cpp:3822

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5653{
5654 // check death state
5657
5658 // Spectator check
5660 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5661 return SPELL_FAILED_NOT_HERE;
5662
5664
5665 sScriptMgr->OnSpellCheckCast(this, strict, res);
5666
5667 if (res != SPELL_CAST_OK)
5668 return res;
5669
5670 // check cooldowns to prevent cheating
5672 {
5674 {
5675 //can cast triggered (by aura only?) spells while have this flag
5678
5680 {
5683 else
5685 }
5686
5687 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5690 }
5693 }
5694
5696 {
5699 }
5700
5701 // Check global cooldown
5704
5705 // only triggered spells can be processed an ended battleground
5708 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5710
5711 if (m_caster->GetTypeId() == TYPEID_PLAYER /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5712 {
5714 !m_caster->IsOutdoors())
5716
5720 }
5721
5722 // only check at first call, Stealth auras are already removed at second call
5723 // for now, ignore triggered spells
5725 {
5726 bool checkForm = true;
5727 // Ignore form req aura
5729 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5730 {
5731 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5732 continue;
5733 checkForm = false;
5734 break;
5735 }
5736 if (checkForm)
5737 {
5738 // Cannot be used in this stance/form
5740 if (shapeError != SPELL_CAST_OK)
5741 return shapeError;
5742
5745 }
5746 }
5747
5749 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5750 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5752
5753 bool reqCombat = true;
5755 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5756 {
5757 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5758 {
5759 m_needComboPoints = false;
5760 if ((*j)->GetMiscValue() == 1)
5761 {
5762 reqCombat = false;
5763 break;
5764 }
5765 }
5766 }
5767
5768 // caster state requirements
5769 // not for triggered spells (needed by execute)
5771 {
5776
5777 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5782
5783 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5785 }
5786
5787 // Xinef: exploit protection
5789 {
5791 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5792 if (instanceScript->IsEncounterInProgress())
5793 {
5794 if (Group* group = m_caster->ToPlayer()->GetGroup())
5795 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5796 if (Player* member = itr->GetSource())
5797 if (member->IsInMap(m_caster))
5798 if (Unit* victim = member->GetVictim())
5799 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5800 {
5801 m_caster->CombatStart(victim);
5802 victim->AddThreat(m_caster, 1.0f);
5803 break;
5804 }
5806 }
5807 }
5808
5809 // cancel autorepeat spells if cast start when moving
5810 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5812 {
5813 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5816 return SPELL_FAILED_MOVING;
5817 }
5818
5819 Vehicle* vehicle = m_caster->GetVehicle();
5821 {
5822 uint16 checkMask = 0;
5823 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5824 {
5825 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5827 {
5828 SpellShapeshiftEntry const* shapeShiftEntry = sSpellShapeshiftStore.LookupEntry(effInfo->MiscValue);
5829 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5830 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5831 break;
5832 }
5833 }
5834
5837
5838 if (!checkMask)
5839 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5840
5841 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5842 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5844 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->GetTypeId() == TYPEID_PLAYER)
5846 }
5847
5848 // check spell cast conditions from database
5849 {
5852 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5853 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5854 {
5855 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5856 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5857 {
5861 }
5862 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5865 }
5866 }
5867
5868 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5869 // those spells may have incorrect target entries or not filled at all (for example 15332)
5870 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5871 // also, such casts shouldn't be sent to client
5872 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5874 {
5875 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5876 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5878 {
5880 if (castResult != SPELL_CAST_OK)
5881 return castResult;
5882 }
5883 }
5884
5885 if (Unit* target = m_targets.GetUnitTarget())
5886 {
5887 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5888 if (castResult != SPELL_CAST_OK)
5889 return castResult;
5890
5891 if (target != m_caster)
5892 {
5893 // Must be behind the target
5894 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5896
5897 // Target must be facing you
5898 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5900
5903 {
5904 bool castedByGameobject = false;
5905 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5907 {
5908 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5909 }
5910 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5911 {
5912 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5913 {
5914 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5915 }
5916 }
5917
5918 if (castedByGameobject)
5919 {
5920 // If spell casted by gameobject then ignore M2 models
5921 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5922 }
5923
5925 {
5927 }
5928 }
5929 }
5930 }
5931
5932 // Check for line of sight for spells with dest
5933 if (m_targets.HasDst())
5934 {
5935 float x, y, z;
5936 m_targets.GetDstPos()->GetPosition(x, y, z);
5937
5940 {
5941 bool castedByGameobject = false;
5942 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5944 {
5945 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5946 }
5947 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5948 {
5949 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5950 {
5951 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5952 }
5953 }
5954
5955 if (castedByGameobject)
5956 {
5957 // If spell casted by gameobject then ignore M2 models
5958 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5959 }
5960
5962 {
5964 }
5965 }
5966 }
5967
5968 // check pet presence
5969 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5970 {
5971 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5972 {
5974 {
5975 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5977 else
5978 return SPELL_FAILED_NO_PET;
5979 }
5980 break;
5981 }
5982 }
5983 // Spell casted only on battleground
5985 if (!m_caster->ToPlayer()->InBattleground())
5987
5988 // do not allow spells to be cast in arenas
5989 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5990 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5993 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5994 if (mapEntry->IsBattleArena())
5996
5997 // zone check
5999 {
6000 uint32 zone, area;
6001 m_caster->GetZoneAndAreaId(zone, area);
6002
6004 m_caster->GetTypeId() == TYPEID_PLAYER ? m_caster->ToPlayer() : nullptr);
6005 if (locRes != SPELL_CAST_OK)
6006 return locRes;
6007 }
6008
6009 // not let players cast spells at mount (and let do it to creatures)
6012 {
6013 if (m_caster->IsInFlight())
6015 else
6017 }
6018
6019 SpellCastResult castResult = SPELL_CAST_OK;
6020
6021 // always (except passive spells) check items (focus object can be required for any type casts)
6022 if (!m_spellInfo->IsPassive())
6023 {
6024 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6025 castResult = CheckSpellFocus();
6026 if (castResult != SPELL_CAST_OK)
6027 return castResult;
6028
6029 castResult = CheckItems();
6030 if (castResult != SPELL_CAST_OK)
6031 return castResult;
6032 }
6033
6034 // Triggered spells also have range check
6036 castResult = CheckRange(strict);
6037 if (castResult != SPELL_CAST_OK)
6038 return castResult;
6039
6041 {
6042 castResult = CheckPower();
6043 if (castResult != SPELL_CAST_OK)
6044 return castResult;
6045 }
6046
6047 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6049 {
6051 if (castResult != SPELL_CAST_OK)
6052 return castResult;
6053
6054 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6056 {
6058 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6059 if (itr->type == m_spellInfo->Mechanic)
6061 }
6062 }
6063
6064 // script hook
6065 castResult = CallScriptCheckCastHandlers();
6066 if (castResult != SPELL_CAST_OK)
6067 return castResult;
6068
6069 bool hasDispellableAura = false;
6070 bool hasNonDispelEffect = false;
6071 uint32 dispelMask = 0;
6072 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6073 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6074 {
6076 {
6077 hasDispellableAura = true;
6078 break;
6079 }
6080
6081 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6082 }
6083 else if (m_spellInfo->Effects[i].IsEffect())
6084 {
6085 hasNonDispelEffect = true;
6086 break;
6087 }
6088
6089 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6090 {
6091 if (Unit* target = m_targets.GetUnitTarget())
6092 {
6093 // Xinef: do not allow to cast on hostile targets in sanctuary
6094 if (!m_caster->IsFriendlyTo(target))
6095 {
6096 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6097 {
6098 // Xinef: fix for duels
6099 Player* player = m_caster->ToPlayer();
6100 if (!player || !player->duel || target != player->duel->Opponent)
6102 }
6103 }
6104
6105 DispelChargesList dispelList;
6106 target->GetDispellableAuraList(m_caster, dispelMask, dispelList);
6107 if (dispelList.empty())
6109 }
6110 }
6111
6112 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6113 {
6114 // for effects of spells that have only one target
6115 switch (m_spellInfo->Effects[i].Effect)
6116 {
6117 case SPELL_EFFECT_DUMMY:
6118 {
6120 {
6121 // Raise Ally
6122 if( m_spellInfo->Id == 61999 )
6123 {
6124 Unit* target = m_targets.GetUnitTarget();
6125 if (!target)
6127
6128 if (target->IsAlive()) // not discovered attributeEx5?
6130 }
6131 }
6132 break;
6133 }
6135 {
6138
6139 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6140 break;
6141
6142 Pet* pet = m_caster->ToPlayer()->GetPet();
6143
6144 if (!pet)
6145 return SPELL_FAILED_NO_PET;
6146
6147 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6148
6149 if (!learn_spellproto)
6151
6152 if (m_spellInfo->SpellLevel > pet->getLevel())
6153 return SPELL_FAILED_LOWLEVEL;
6154
6155 break;
6156 }
6158 {
6159 // check target only for unit target case
6161 {
6164
6165 Pet* pet = unitTarget->ToPet();
6166 if (!pet || pet->GetOwner() != m_caster)
6168
6169 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6170
6171 if (!learn_spellproto)
6173
6174 if (m_spellInfo->SpellLevel > pet->getLevel())
6175 return SPELL_FAILED_LOWLEVEL;
6176 }
6177 break;
6178 }
6180 {
6181 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6182 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6183 if (m_caster->HasAura(gp->SpellId))
6185 break;
6186 }
6188 {
6191
6192 Item* foodItem = m_targets.GetItemTarget();
6193 if (!foodItem)
6195
6196 Pet* pet = m_caster->ToPlayer()->GetPet();
6197
6198 if (!pet)
6199 return SPELL_FAILED_NO_PET;
6200
6201 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6203
6204 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6206
6207 if (m_caster->IsInCombat() || pet->IsInCombat())
6209
6210 break;
6211 }
6214 {
6215 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6217 if (Unit* target = m_targets.GetUnitTarget())
6218 if (target != m_caster && target->getPowerType() != Powers(m_spellInfo->Effects[i].MiscValue))
6220 break;
6221 }
6223 {
6225 {
6227 }
6228
6230 {
6231 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6232 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6234 }
6236 {
6237 // Exception for Master's Call
6238 if (m_spellInfo->Id != 54216)
6239 {
6240 return SPELL_FAILED_ROOTED;
6241 }
6242 }
6244 if (Unit* target = m_targets.GetUnitTarget())
6245 if (!target->IsAlive())
6247 // Xinef: Pass only explicit unit target spells
6248 // pussywizard:
6250 {
6251 Unit* target = m_targets.GetUnitTarget();
6252 if (!target)
6254
6255 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6256 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6258
6259 float objSize = target->GetCombatReach();
6260 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6261
6262 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6263 m_preGeneratedPath->SetPathLengthLimit(range);
6264
6265 // first try with raycast, if it fails fall back to normal path
6266 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6267 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6268 return SPELL_FAILED_NOPATH;
6269 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6270 return SPELL_FAILED_NOPATH;
6271 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6272 return SPELL_FAILED_NOPATH;
6273
6274 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6275 }
6276 if (Player* player = m_caster->ToPlayer())
6277 player->SetCanTeleport(true);
6278 break;
6279 }
6281 {
6284
6287
6288 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6289 if (!creature->IsCritter() && !creature->loot.isLooted())
6291
6292 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6293
6294 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6295 int32 TargetLevel = m_targets.GetUnitTarget()->getLevel();
6296 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6297 if (ReqValue > skillValue)
6299
6300 break;
6301 }
6303 {
6304 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6305 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6306 break;
6307
6308 if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc.
6309 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6310 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6312
6313 Item* pTempItem = nullptr;
6315 {
6316 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6317 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6318 }
6321
6322 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6323 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6325 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6327
6328 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6329 if (GameObject* go = m_targets.GetGOTarget())
6330 {
6331 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6332 {
6334 }
6335 }
6336 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6338 {
6339 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6340 {
6341 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6343 }
6344 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6347 }
6348
6349 // get the lock entry
6350 uint32 lockId = 0;
6351 if (GameObject* go = m_targets.GetGOTarget())
6352 {
6353 lockId = go->GetGOInfo()->GetLockId();
6354 if (!lockId)
6356 }
6357 else if (Item* itm = m_targets.GetItemTarget())
6358 lockId = itm->GetTemplate()->LockID;
6359
6360 SkillType skillId = SKILL_NONE;
6361 int32 reqSkillValue = 0;
6362 int32 skillValue = 0;
6363
6364 // check lock compatibility
6365 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6366 if (res != SPELL_CAST_OK)
6367 return res;
6368
6369 // chance for fail at lockpicking attempt
6370 // second check prevent fail at rechecks
6371 if (skillId != SKILL_NONE && (!m_selfContainer || ((*m_selfContainer) != this)))
6372 {
6373 // chance for failure in orange lockpick
6374 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6375 {
6377 }
6378 }
6379 break;
6380 }
6382 {
6383 Unit* unitCaster = m_caster->ToUnit();
6384 if (!unitCaster)
6385 {
6387 }
6388
6389 Creature* pet = unitCaster->GetGuardianPet();
6390 if (pet)
6391 {
6392 if (pet->IsAlive())
6393 {
6395 }
6396 }
6397 else if (Player* playerCaster = m_caster->ToPlayer())
6398 {
6399 PetStable& petStable = playerCaster->GetOrInitPetStable();
6400 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6401 {
6402 return SPELL_FAILED_NO_PET;
6403 }
6404 }
6405
6406 break;
6407 }
6408 // This is generic summon effect
6410 {
6411 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6412 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6413 break;
6414 switch (SummonProperties->Category)
6415 {
6417 if (m_caster->GetPetGUID())
6419 [[fallthrough]];
6421 if (m_caster->GetCharmGUID())
6423 break;
6424 }
6425 break;
6426 }
6428 {
6430 {
6435 }
6436 break;
6437 }
6439 {
6440 Unit* unitCaster = m_caster->ToUnit();
6441 if (!unitCaster)
6443
6445 {
6446 if (m_caster->GetPetGUID())
6448 if (m_caster->GetCharmGUID())
6450 }
6451
6452 if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARLOCK && strict)
6453 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6454 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6455
6456 Player* playerCaster = unitCaster->ToPlayer();
6457 if (playerCaster && playerCaster->GetPetStable())
6458 {
6459 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6460 if (info.first)
6461 {
6462 if (info.first->Type == HUNTER_PET)
6463 {
6464 if (!info.first->Health)
6465 {
6466 playerCaster->SendTameFailure(PET_TAME_DEAD);
6468 }
6469
6470 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6471 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6472 {
6473 // if problem in exotic pet
6474 if (creatureInfo && creatureInfo->IsTameable(true))
6476 else
6478
6480 }
6481 }
6482 }
6483 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6484 {
6487 }
6488 }
6489 break;
6490 }
6492 {
6495 if (!m_caster->GetTarget())
6497
6499 if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6501
6502 // Xinef: Implement summon pending error
6503 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6505
6506 // check if our map is dungeon
6507 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6508 if (map->IsDungeon())
6509 {
6510 uint32 mapId = m_caster->GetMap()->GetId();
6511 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6512 /*if (map->IsRaid())
6513 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6514 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6515 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6516
6517 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6518 if (!instance)
6520 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6522 }
6523 break;
6524 }
6525 // RETURN HERE
6527 {
6530
6531 Player* playerCaster = m_caster->ToPlayer();
6532 //
6533 if (!(playerCaster->GetTarget()))
6535
6537
6538 if (!target ||
6539 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6541
6542 // Xinef: Implement summon pending error
6543 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6545
6546 break;
6547 }
6548 case SPELL_EFFECT_LEAP:
6550 {
6551 //Do not allow to cast it before BG starts.
6553 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6554 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6556 break;
6557 }
6559 {
6562
6563 bool found = false;
6565 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6566 {
6567 if( itr->second->GetBase()->IsPassive() )
6568 continue;
6569
6570 if( !itr->second->IsPositive() )
6571 continue;
6572
6573 found = true;
6574 break;
6575 }
6576
6577 if( !found )
6579
6580 break;
6581 }
6583 {
6585 {
6587 return SPELL_FAILED_ROOTED;
6588 else
6590 }
6591 break;
6592 }
6593 // xinef: do not allow to use leaps while rooted
6594 case SPELL_EFFECT_JUMP:
6596 {
6598 return SPELL_FAILED_ROOTED;
6599 break;
6600 }
6602 if (!sScriptMgr->CanSelectSpecTalent(this))
6604 // can't change during already started arena/battleground
6606 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6607 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6609 break;
6610 default:
6611 break;
6612 }
6613 }
6614
6615 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6616 {
6617 switch (m_spellInfo->Effects[i].ApplyAuraName)
6618 {
6619 case SPELL_AURA_DUMMY:
6620 break;
6622 {
6624 return SPELL_FAILED_NO_PET;
6625
6626 Pet* pet = m_caster->ToPlayer()->GetPet();
6627 if (!pet)
6628 return SPELL_FAILED_NO_PET;
6629
6630 if (pet->GetCharmerGUID())
6631 return SPELL_FAILED_CHARMED;
6632 break;
6633 }
6637 {
6638 if (m_caster->GetCharmerGUID())
6639 return SPELL_FAILED_CHARMED;
6640
6641 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6643 {
6644 if (m_caster->GetPetGUID())
6646
6647 if (m_caster->GetCharmGUID())
6649 }
6650 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6651 {
6652 if (m_caster->GetCharmGUID())
6654 }
6655
6656 if (Unit* target = m_targets.GetUnitTarget())
6657 {
6658 if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->IsVehicle())
6660
6661 if (target->IsMounted())
6663
6664 if (target->GetCharmerGUID())
6665 return SPELL_FAILED_CHARMED;
6666
6667 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6669
6670 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6672
6673 int32 damage = CalculateSpellDamage(i, target);
6674 if (damage && int32(target->getLevel()) > damage)
6676 }
6677
6678 break;
6679 }
6680 case SPELL_AURA_MOUNTED:
6681 {
6682 // Xinef: disallow casting in water for mounts not increasing water movement Speed
6685
6686 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6687 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6688 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6689 if (it)
6690 allowMount = it->AllowMount;
6691 if (m_caster->GetTypeId() == TYPEID_PLAYER && !allowMount && !m_spellInfo->AreaGroupId)
6693
6696
6697 // xinef: dont allow to cast mounts in specific transforms
6698 if (m_caster->getTransForm())
6699 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6700 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6701 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6703
6704 break;
6705 }
6707 {
6708 if (!m_targets.GetUnitTarget())
6710
6711 // can be casted at non-friendly unit or own pet/charm
6714
6715 break;
6716 }
6717 case SPELL_AURA_FLY:
6719 {
6720 // Xinef: added water check
6721 if (m_caster->IsInWater())
6723
6724 // not allow cast fly spells if not have req. skills (all spells is self target)
6725 // allow always ghost flight spells
6727 {
6728 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6729 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6730 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6731 return SPELL_FAILED_NOT_HERE;
6732 }
6733 break;
6734 }
6736 {
6737 if (m_spellInfo->Effects[i].IsTargetingArea())
6738 break;
6739
6741 break;
6742
6743 if (!m_targets.GetUnitTarget())
6745
6748
6749 break;
6750 }
6751 case SPELL_AURA_HOVER:
6752 {
6754 {
6756 }
6757 break;
6758 }
6760 {
6761 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6762 {
6764 }
6765 break;
6766 }
6767 default:
6768 break;
6769 }
6770 }
6771
6772 // check trade slot case (last, for allow catch any another cast problems)
6774 {
6775 if (m_CastItem)
6777
6780
6781 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6782
6783 if (!my_trade)
6785
6787 if (slot != TRADE_SLOT_NONTRADED)
6789
6790 if (!IsTriggered())
6791 if (my_trade->GetSpell())
6793 }
6794
6795 // check if caster has at least 1 combo point on target for spells that require combo points
6797 {
6799 {
6801 {
6803 }
6804 }
6805 else
6806 {
6807 if (!m_caster->GetComboPoints())
6808 {
6810 }
6811 }
6812 }
6813
6814 // xinef: check relic cooldown
6818
6819 // all ok
6820 return SPELL_CAST_OK;
6821}
constexpr auto IN_MILLISECONDS
Definition: Common.h:62
constexpr auto MINUTE
Definition: Common.h:56
std::int32_t int32
Definition: Define.h:104
std::uint16_t uint16
Definition: Define.h:109
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:198
@ STATUS_IN_PROGRESS
Definition: Battleground.h:197
#define sConditionMgr
Definition: ConditionMgr.h:289
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:139
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
DBCStorage< SpellShapeshiftEntry > sSpellShapeshiftStore(SpellShapeshiftfmt)
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
@ GO_STATE_READY
Definition: GameObject.h:735
@ INVTYPE_RELIC
Definition: ItemTemplate.h:293
@ HUNTER_PET
Definition: PetDefines.h:32
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:498
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
@ MOVEMENTFLAG_FALLING_FAR
Definition: Unit.h:565
#define WORLD_TRIGGER
Definition: Unit.h:36
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: Unit.h:505
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:241
@ UNIT_STATE_ROOT
Definition: Unit.h:335
@ UNIT_STATE_CHARGING
Definition: Unit.h:342
@ UNIT_FLAG_SKINNABLE
Definition: Unit.h:474
LineOfSightChecks
Definition: Map.h:190
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:197
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
@ PATHFIND_SHORT
Definition: PathGenerator.h:53
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:50
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition: SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_MOD_INCREASE_SWIM_SPEED
Definition: SpellAuraDefines.h:121
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition: SpellAuraDefines.h:360
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:83
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:62
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:61
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition: SpellDefines.h:133
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition: SpellDefines.h:143
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:144
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition: SpellDefines.h:142
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition: SpellDefines.h:132
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:145
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:179
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition: SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
#define SPELL_RELIC_COOLDOWN
Definition: SpellMgr.h:34
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:461
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:462
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:463
Difficulty
Definition: DBCEnums.h:271
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:267
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1538
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1532
Powers
Definition: SharedDefines.h:240
@ POWER_MANA
Definition: SharedDefines.h:241
@ SPELL_ATTR7_DEBUG_SPELL
Definition: SharedDefines.h:616
@ SPELL_EFFECT_DUMMY
Definition: SharedDefines.h:753
@ SPELL_EFFECT_LEAP
Definition: SharedDefines.h:779
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:812
@ SPELL_EFFECT_STUCK
Definition: SharedDefines.h:834
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition: SharedDefines.h:902
@ SPELL_EFFECT_APPLY_GLYPH
Definition: SharedDefines.h:824
@ SPELL_EFFECT_FEED_PET
Definition: SharedDefines.h:851
@ SPELL_EFFECT_SUMMON_PLAYER
Definition: SharedDefines.h:835
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:792
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition: SharedDefines.h:793
@ SPELL_EFFECT_RESURRECT_PET
Definition: SharedDefines.h:859
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:888
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:778
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:758
@ SPELL_EFFECT_RESURRECT
Definition: SharedDefines.h:768
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:846
@ SPELL_EFFECT_RESURRECT_NEW
Definition: SharedDefines.h:863
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition: SharedDefines.h:912
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:786
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:791
@ SPELL_EFFECT_SKINNING
Definition: SharedDefines.h:845
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition: SharedDefines.h:903
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:783
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition: SharedDefines.h:876
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition: SharedDefines.h:807
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1525
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:565
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1386
@ TARGET_GAMEOBJECT_TARGET
Definition: SharedDefines.h:1399
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:430
@ SPELL_ATTR1_INITIATE_COMBAT
Definition: SharedDefines.h:400
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:476
@ PET_TAME_NOPET_AVAILABLE
Definition: SharedDefines.h:3655
@ PET_TAME_DEAD
Definition: SharedDefines.h:3658
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition: SharedDefines.h:3660
@ CLASS_WARLOCK
Definition: SharedDefines.h:121
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1371
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3504
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3515
SpellCustomErrors
Definition: SharedDefines.h:1114
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition: SharedDefines.h:1180
SpellAttr0
Definition: SharedDefines.h:353
@ SPELL_ATTR0_ONLY_INDOORS
Definition: SharedDefines.h:368
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:380
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition: SharedDefines.h:369
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:378
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:360
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:377
@ SPELL_ATTR0_ONLY_STEALTHED
Definition: SharedDefines.h:371
AuraStateType
Definition: SharedDefines.h:1260
DispelType
Definition: SharedDefines.h:1343
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition: SharedDefines.h:1042
@ SPELL_FAILED_NOT_INFRONT
Definition: SharedDefines.h:982
@ SPELL_FAILED_MOVING
Definition: SharedDefines.h:972
@ SPELL_FAILED_NOT_MOUNTED
Definition: SharedDefines.h:985
@ SPELL_FAILED_AFFECTING_COMBAT
Definition: SharedDefines.h:922
@ SPELL_FAILED_CASTER_AURASTATE
Definition: SharedDefines.h:943
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition: SharedDefines.h:1007
@ SPELL_FAILED_NOT_KNOWN
Definition: SharedDefines.h:984
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition: SharedDefines.h:956
@ SPELL_FAILED_NOT_HERE
Definition: SharedDefines.h:981
@ SPELL_FAILED_ROOTED
Definition: SharedDefines.h:1024
@ SPELL_FAILED_TARGET_NOT_DEAD
Definition: SharedDefines.h:1040
@ SPELL_FAILED_WRONG_PET_FOOD
Definition: SharedDefines.h:1056
@ SPELL_FAILED_CUSTOM_ERROR
Definition: SharedDefines.h:1093
@ SPELL_FAILED_SUMMON_PENDING
Definition: SharedDefines.h:1104
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition: SharedDefines.h:1067
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition: SharedDefines.h:932
@ SPELL_FAILED_TRY_AGAIN
Definition: SharedDefines.h:1053
@ SPELL_FAILED_NO_COMBO_POINTS
Definition: SharedDefines.h:999
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition: SharedDefines.h:928
@ SPELL_FAILED_ALREADY_OPEN
Definition: SharedDefines.h:929
@ SPELL_FAILED_NOT_TRADING
Definition: SharedDefines.h:992
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition: SharedDefines.h:1008
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition: SharedDefines.h:1004
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:1087
@ SPELL_FAILED_NOT_BEHIND
Definition: SharedDefines.h:978
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition: SharedDefines.h:927
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition: SharedDefines.h:1058
@ SPELL_FAILED_HIGHLEVEL
Definition: SharedDefines.h:957
@ SPELL_FAILED_LOWLEVEL
Definition: SharedDefines.h:969
@ SPELL_FAILED_NOT_READY
Definition: SharedDefines.h:988
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:1063
@ SPELL_FAILED_NOT_IN_ARENA
Definition: SharedDefines.h:1072
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition: SharedDefines.h:963
@ SPELL_FAILED_ONLY_STEALTHED
Definition: SharedDefines.h:1016
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition: SharedDefines.h:1039
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition: SharedDefines.h:1009
@ SPELL_FAILED_CANT_BE_CHARMED
Definition: SharedDefines.h:934
@ SPELL_FAILED_CASTER_DEAD
Definition: SharedDefines.h:944
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition: SharedDefines.h:1076
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition: SharedDefines.h:1103
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition: SharedDefines.h:1107
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition: SharedDefines.h:1047
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition: SharedDefines.h:989
@ SPELL_FAILED_UNIQUE_GLYPH
Definition: SharedDefines.h:1097
@ SPELL_FAILED_ONLY_OUTDOORS
Definition: SharedDefines.h:1014
@ SPELL_FAILED_CHARMED
Definition: SharedDefines.h:945
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:968
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition: SharedDefines.h:1026
@ SPELL_FAILED_NO_PET
Definition: SharedDefines.h:1005
@ SPELL_FAILED_NOPATH
Definition: SharedDefines.h:977
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1028
@ SPELL_FAILED_ONLY_INDOORS
Definition: SharedDefines.h:1011
@ SPELL_FAILED_NOT_ON_TAXI
Definition: SharedDefines.h:986
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1036
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: SharedDefines.h:519
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:518
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3257
@ SUMMON_CATEGORY_PUPPET
Definition: SharedDefines.h:3258
SkillType
Definition: SharedDefines.h:2835
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition: SharedDefines.h:588
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:402
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:250
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Battlefield.h:205
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:341
Definition: Battleground.h:293
Definition: ConditionMgr.h:181
Condition * mLastFailedCondition
Definition: ConditionMgr.h:183
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:182
uint32 ErrorType
Definition: ConditionMgr.h:204
uint8 ConditionTarget
Definition: ConditionMgr.h:208
uint32 ErrorTextId
Definition: ConditionMgr.h:205
Loot loot
Definition: Creature.h:217
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:196
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2827
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:246
bool IsTameable(bool exotic) const
Definition: CreatureData.h:263
Definition: TemporarySummon.h:40
uint32 type
Definition: GameObject.h:43
Definition: GameObject.h:813
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:829
bool IsLocked() const
Definition: Item.h:247
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:546
bool IsPotion() const
Definition: Item.h:328
uint32 ItemLevel
Definition: ItemTemplate.h:644
uint32 LockID
Definition: ItemTemplate.h:678
uint32 InventoryType
Definition: ItemTemplate.h:641
Unit * ToUnit()
Definition: Object.h:200
Map * GetMap() const
Definition: Object.h:517
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1194
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }) const
Definition: Object.cpp:1349
bool IsOutdoors() const
Definition: Object.cpp:3085
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition: Object.cpp:1328
float GetVisibilityRange() const
Definition: Object.cpp:1647
uint32 GetAreaId() const
Definition: Object.cpp:3068
uint32 GetZoneId() const
Definition: Object.cpp:3060
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3076
uint64 GetRawValue() const
Definition: ObjectGuid.h:144
bool IsPlayer() const
Definition: ObjectGuid.h:170
bool IsGameObject() const
Definition: ObjectGuid.h:173
void GetPosition(float &x, float &y) const
Definition: Position.h:122
uint32 GetMapId() const
Definition: Position.h:276
Player * GetOwner() const
Definition: Pet.cpp:2438
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1403
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1421
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:162
Definition: PetDefines.h:197
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:220
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:223
void SetCanTeleport(bool value)
Definition: Player.h:2447
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1835
bool CanTameExoticPets() const
Definition: Player.h:2137
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:12930
bool InBattleground() const
Definition: Player.h:2200
PetStable * GetPetStable()
Definition: Player.h:1178
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:11915
WorldSession * GetSession() const
Definition: Player.h:1947
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16024
uint32 GetLastPotionId()
Definition: Player.h:1761
Group * GetGroup()
Definition: Player.h:2417
bool IsGameMaster() const
Definition: Player.h:1136
time_t GetSummonExpireTimer() const
Definition: Player.h:1083
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6731
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1090
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1827
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:440
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:1416
Vehicle * GetVehicle() const
Definition: Unit.h:2622
Unit * GetOwner() const
Definition: Unit.cpp:11404
Pet * ToPet()
Definition: Unit.h:2666
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:2686
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:2321
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:2687
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:22100
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:14385
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:1484
bool IsInSanctuary() const
Definition: Unit.h:1514
uint8 getClass() const
Definition: Unit.h:1424
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:6565
float GetCombatReach() const override
Definition: Unit.h:1347
UnitFlags GetUnitFlags() const
Definition: Unit.h:1477
TempSummon * ToTempSummon()
Definition: Unit.h:2668
bool HasStealthAura() const
Definition: Unit.h:1742
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:6454
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:1312
bool IsInFlight() const
Definition: Unit.h:1712
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:2395
void SendTameFailure(uint8 result)
Definition: Unit.cpp:20864
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:2542
virtual bool IsInWater() const
Definition: Unit.cpp:4932
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:11351
bool isMoving() const
Definition: Unit.h:2648
ObjectGuid GetCharmGUID() const
Definition: Unit.h:2038
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:2410
bool IsMounted() const
Definition: Unit.h:1540
Unit * GetVictim() const
Definition: Unit.h:1386
bool IsCritter() const
Definition: Unit.h:1710
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:2030
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition: Unit.h:2558
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:2036
uint32 getTransForm() const
Definition: Unit.h:2431
Powers getPowerType() const
Definition: Unit.h:1457
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5986
bool IsTotem() const
Definition: Unit.h:1415
Guardian * GetGuardianPet() const
Definition: Unit.cpp:11455
ObjectGuid GetTarget() const
Definition: Unit.h:2701
bool IsInCombat() const
Definition: Unit.h:1724
ObjectGuid GetPetGUID() const
Definition: Unit.h:2040
Definition: Vehicle.h:30
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:585
Definition: Group.h:168
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:140
bool isLooted() const
Definition: LootMgr.h:368
Definition: Map.h:273
bool AllowMount
Definition: Map.h:276
bool IsDungeon() const
Definition: Map.h:447
bool IsBattlegroundOrArena() const
Definition: Map.h:455
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3295
uint32 GetId() const
Definition: Map.h:378
Difficulty GetDifficulty() const
Definition: Map.h:442
uint32 GetRecruiterId() const
Definition: WorldSession.h:523
uint32 GetAccountId() const
Definition: WorldSession.h:359
GameObject * GetGOTarget() const
Get GameObject Target.
Definition: Spell.cpp:305
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:138
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:775
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7755
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8358
SpellCastResult CheckItems()
Definition: Spell.cpp:7187
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:477
SpellCastResult CheckPower()
Definition: Spell.cpp:7142
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6859
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8557
bool IsTriggered() const
Definition: Spell.h:552
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7056
bool HasGlobalCooldown() const
Definition: Spell.cpp:8832
Definition: SpellInfo.h:247
int32 MiscValue
Definition: SpellInfo.h:261
uint32 ApplyAuraName
Definition: SpellInfo.h:252
uint32 PreventionType
Definition: SpellInfo.h:388
uint32 CasterAuraSpell
Definition: SpellInfo.h:341
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1417
uint32 Mechanic
Definition: SpellInfo.h:321
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2023
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2376
bool IsSelfCast() const
Definition: SpellInfo.cpp:1073
uint32 CasterAuraState
Definition: SpellInfo.h:337
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1215
uint32 CasterAuraStateNot
Definition: SpellInfo.h:339
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1969
int32 AreaGroupId
Definition: SpellInfo.h:389
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2303
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2037
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1016
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1472
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:343
uint32 SpellFamilyName
Definition: SpellInfo.h:385
uint32 AuraInterruptFlags
Definition: SpellInfo.h:351
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1919
Definition: DBCStructure.h:519
Definition: DBCStructure.h:1012
Definition: DBCStructure.h:1308
bool IsDungeon() const
Definition: DBCStructure.h:1334
Definition: DBCStructure.h:1778
uint32 flags1
Definition: DBCStructure.h:1783
Definition: DBCStructure.h:1871
uint32 Category
Definition: DBCStructure.h:1873
Definition: DBCStructure.h:2026
uint32 m_flags
Definition: DBCStructure.h:2028

References _triggeredCastFlags, InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::getClass(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::getLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::getPowerType(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Object::GetTypeId(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), SpellInfo::IsCooldownStartedOnEvent(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SKILL_LOCKPICKING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_INCREASE_SWIM_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_DUMMY, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_DEAD, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, TYPEID_PLAYER, TYPEID_UNIT, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6860{
6861 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6863 return SPELL_CAST_OK;
6864
6865 uint8 school_immune = 0;
6866 uint32 mechanic_immune = 0;
6867 uint32 dispel_immune = 0;
6868
6869 // Check if the spell grants school or mechanic immunity.
6870 // We use bitmasks so the loop is done only once and not on every aura check below.
6872 {
6873 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6874 {
6875 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6876 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6877 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6878 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6879 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6880 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6881 }
6882 // immune movement impairment and loss of control
6883 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6884 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6886 }
6887
6889
6890 // Glyph of Pain Suppression
6891 // there is no other way to handle it
6892 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6893 usableInStun = false;
6894
6895 // Check whether the cast should be prevented by any state you might have.
6896 SpellCastResult prevented_reason = SPELL_CAST_OK;
6897 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6898 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6899
6900 // Xinef: if spell is triggered check preventionType only
6901 if (!preventionOnly)
6902 {
6903 if (unitflag & UNIT_FLAG_STUNNED)
6904 {
6905 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6906 if (usableInStun)
6907 {
6908 bool foundNotStun = false;
6909 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6910 // Barkskin should skip sleep effects, sap and fears
6911 if (m_spellInfo->Id == 22812)
6912 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6913 // Hand of Freedom, can be used while sapped
6914 if (m_spellInfo->Id == 1044)
6915 mask |= 1 << MECHANIC_SAPPED;
6917 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6918 {
6919 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6920 {
6921 foundNotStun = true;
6922 break;
6923 }
6924 }
6925 if (foundNotStun)
6926 prevented_reason = SPELL_FAILED_STUNNED;
6927 }
6928 else
6929 prevented_reason = SPELL_FAILED_STUNNED;
6930 }
6932 prevented_reason = SPELL_FAILED_CONFUSED;
6934 prevented_reason = SPELL_FAILED_FLEEING;
6935 }
6936
6937 // Xinef: if there is no prevented_reason, check prevention types
6938 if (prevented_reason == SPELL_CAST_OK)
6939 {
6941 prevented_reason = SPELL_FAILED_SILENCED;
6943 prevented_reason = SPELL_FAILED_PACIFIED;
6944 }
6945
6946 // Attr must make flag drop spell totally immune from all effects
6947 if (prevented_reason != SPELL_CAST_OK)
6948 {
6949 if (school_immune || mechanic_immune || dispel_immune)
6950 {
6951 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6953 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6954 {
6955 Aura const* aura = itr->second->GetBase();
6956 SpellInfo const* auraInfo = aura->GetSpellInfo();
6957 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6958 continue;
6959 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6960 continue;
6961 if (auraInfo->GetDispelMask() & dispel_immune)
6962 continue;
6963
6964 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6965 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6966 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6967 {
6968 if (AuraEffect* part = aura->GetEffect(i))
6969 {
6970 switch (part->GetAuraType())
6971 {
6973 {
6974 uint32 mask = 1 << MECHANIC_STUN;
6975 // Barkskin should skip sleep effects, sap and fears
6976 if (m_spellInfo->Id == 22812)
6977 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6978 // Hand of Freedom, can be used while sapped
6979 if (m_spellInfo->Id == 1044)
6980 mask |= 1 << MECHANIC_SAPPED;
6981
6982 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6983 return SPELL_FAILED_STUNNED;
6984 break;
6985 }
6988 return SPELL_FAILED_CONFUSED;
6989 break;
6992 return SPELL_FAILED_FLEEING;
6993 break;
6998 return SPELL_FAILED_PACIFIED;
7000 return SPELL_FAILED_SILENCED;
7001 break;
7002 default:
7003 break;
7004 }
7005 }
7006 }
7007 }
7008 }
7009 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
7010 else
7011 return prevented_reason;
7012 }
7013 return SPELL_CAST_OK;
7014}
@ UNIT_FLAG_STUNNED
Definition: Unit.h:466
@ UNIT_FLAG_PACIFIED
Definition: Unit.h:465
@ UNIT_FLAG_CONFUSED
Definition: Unit.h:470
@ UNIT_FLAG_FLEEING
Definition: Unit.h:471
@ UNIT_FLAG_SILENCED
Definition: Unit.h:461
@ SPELL_AURA_DISPEL_IMMUNITY
Definition: SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition: SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition: SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition: SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition: SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition: SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
@ SPELL_PREVENTION_TYPE_SILENCE
Definition: SharedDefines.h:1526
@ SPELL_PREVENTION_TYPE_PACIFY
Definition: SharedDefines.h:1527
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:542
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition: SharedDefines.h:556
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition: SharedDefines.h:557
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:406
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition: SharedDefines.h:407
@ MECHANIC_STUN
Definition: SharedDefines.h:1309
@ MECHANIC_FREEZE
Definition: SharedDefines.h:1310
@ MECHANIC_SLEEP
Definition: SharedDefines.h:1307
@ MECHANIC_SAPPED
Definition: SharedDefines.h:1327
@ MECHANIC_HORROR
Definition: SharedDefines.h:1321
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition: SharedDefines.h:1333
@ SPELL_FAILED_STUNNED
Definition: SharedDefines.h:1029
@ SPELL_FAILED_CONFUSED
Definition: SharedDefines.h:947
@ SPELL_FAILED_SILENCED
Definition: SharedDefines.h:1025
@ SPELL_FAILED_FLEEING
Definition: SharedDefines.h:955
@ SPELL_FAILED_PACIFIED
Definition: SharedDefines.h:1019
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition: SharedDefines.h:578
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition: Unit.h:1299
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:2152
Definition: SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition: SpellAuras.h:175
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:1974

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:452

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8491{
8492 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8494}
#define ASSERT
Definition: Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7927{
7928 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7929 {
7934 if (target->GetTypeId() == TYPEID_UNIT && target->IsVehicle())
7935 return false;
7936 if (target->IsMounted())
7937 return false;
7938 if (target->GetCharmerGUID())
7939 return false;
7940 if (int32 damage = CalculateSpellDamage(eff, target))
7941 if ((int32)target->getLevel() > damage)
7942 return false;
7943 break;
7944 default:
7945 break;
7946 }
7947
7948 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7949 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7950 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->GetTypeId() == TYPEID_UNIT && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7951 return true;
7952
7953 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7956 {
7957 return true;
7958 }
7959
7961 //Check targets for LOS visibility (except spells without range limitations)
7962 switch (m_spellInfo->Effects[eff].Effect)
7963 {
7965 // player far away, maybe his corpse near?
7966 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7967 {
7969 return false;
7970
7972 if (!corpse)
7973 return false;
7974
7975 if (target->GetGUID() != corpse->GetOwnerGUID())
7976 return false;
7977
7979 return false;
7980 }
7981 break;
7983 {
7985 {
7986 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7987 return true;
7988
7989 return false;
7990 }
7991
7993 if (!corpse)
7994 return false;
7995
7996 if (target->GetGUID() != corpse->GetOwnerGUID())
7997 return false;
7998
8000 return false;
8001
8003 return false;
8004 }
8005 break;
8007 if (m_caster->GetTypeId() != TYPEID_PLAYER || target->GetTypeId() != TYPEID_PLAYER)
8008 return false;
8009 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8010 return false;
8011 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8012 return false;
8013 if (target->ToPlayer()->getLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8014 return false;
8015 break;
8016 default: // normal case
8017 {
8018 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8019 GameObject* gobCaster = nullptr;
8021 {
8023 }
8024 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8025 {
8026 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8027 {
8028 gobCaster = tempSummon->GetSummonerGameObject();
8029 }
8030 }
8031
8032 if (gobCaster)
8033 {
8034 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8035 {
8036 return true;
8037 }
8038
8039 // If spell casted by gameobject then ignore M2 models
8040 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8041 }
8042
8043 if (target != m_caster)
8044 {
8045 if (m_targets.HasDst())
8046 {
8047 float x = m_targets.GetDstPos()->GetPositionX();
8048 float y = m_targets.GetDstPos()->GetPositionY();
8049 float z = m_targets.GetDstPos()->GetPositionZ();
8050
8051 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8052 {
8053 return false;
8054 }
8055 }
8057 {
8058 return false;
8059 }
8060 }
8061 break;
8062 }
8063 }
8064
8065 return true;
8066}
@ SPELL_DISABLE_LOS
Definition: DisableMgr.h:49
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:29
@ CORPSE_FLAG_LOOTABLE
Definition: Corpse.h:45
@ CORPSE_FIELD_FLAGS
Definition: UpdateFields.h:427
@ UNIT_FLAG_NOT_SELECTABLE
Definition: Unit.h:473
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:115
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:252
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition: SharedDefines.h:866
#define sWorld
Definition: World.h:458
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:304
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:184
Definition: Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition: Corpse.h:68
bool IsIgnoringLOSChecks() const
Definition: GameObject.h:652
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:891
bool IsARecruiter() const
Definition: WorldSession.h:524
ObjectGuid GetCorpseTargetGUID() const
Definition: Spell.cpp:327

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::getLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), DisableMgr::IsDisabledFor(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7188{
7189 Player* player = m_caster->ToPlayer();
7190 if (!player)
7191 {
7192 // Non-player case: Check if creature is disarmed
7194 {
7196 }
7197
7198 return SPELL_CAST_OK;
7199 }
7200
7201 if (!m_CastItem)
7202 {
7203 if (m_castItemGUID)
7205 }
7206 else
7207 {
7208 uint32 itemid = m_CastItem->GetEntry();
7209 if (!player->HasItemCount(itemid))
7211
7212 ItemTemplate const* proto = m_CastItem->GetTemplate();
7213 if (!proto)
7215
7216 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7217 if (proto->Spells[i].SpellCharges)
7218 if (m_CastItem->GetSpellCharges(i) == 0)
7220
7221 // consumable cast item checks
7223 {
7224 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7225 SpellCastResult failReason = SPELL_CAST_OK;
7226 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7227 {
7228 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7229 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7230 continue;
7231
7232 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7233 {
7235 {
7237 continue;
7238 }
7239 else
7240 {
7241 failReason = SPELL_CAST_OK;
7242 break;
7243 }
7244 }
7245
7246 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7247 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7248 {
7249 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7250 {
7252 continue;
7253 }
7254
7255 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7257 {
7259 continue;
7260 }
7261 else
7262 {
7263 failReason = SPELL_CAST_OK;
7264 break;
7265 }
7266 }
7267 }
7268 if (failReason != SPELL_CAST_OK)
7269 return failReason;
7270 }
7271 }
7272
7273 // check target item
7275 {
7278
7279 if (!m_targets.GetItemTarget())
7281
7284 }
7285 // if not item target then required item must be equipped
7286 else
7287 {
7288 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7289 //if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7292 }
7293
7294 // do not take reagents for these item casts
7296 {
7298 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7299 if (!checkReagents)
7300 if (Item* targetItem = m_targets.GetItemTarget())
7301 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7302 checkReagents = true;
7303
7304 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7305 if (checkReagents)
7306 {
7307 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7308 {
7309 if (m_spellInfo->Reagent[i] <= 0)
7310 continue;
7311
7312 uint32 itemid = m_spellInfo->Reagent[i];
7313 uint32 itemcount = m_spellInfo->ReagentCount[i];
7314
7315 // if CastItem is also spell reagent
7316 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7317 {
7318 ItemTemplate const* proto = m_CastItem->GetTemplate();
7319 if (!proto)
7321 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7322 {
7323 // CastItem will be used up and does not count as reagent
7324 int32 charges = m_CastItem->GetSpellCharges(s);
7325 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7326 {
7327 ++itemcount;
7328 break;
7329 }
7330 }
7331 }
7332 if (!player->HasItemCount(itemid, itemcount))
7333 return SPELL_FAILED_REAGENTS;
7334 }
7335 }
7336
7337 // check totem-item requirements (items presence in inventory)
7338 uint32 totems = 2;
7339 for (int i = 0; i < 2; ++i)
7340 {
7341 if (m_spellInfo->Totem[i] != 0)
7342 {
7343 if (player->HasItemCount(m_spellInfo->Totem[i]))
7344 {
7345 totems -= 1;
7346 continue;
7347 }
7348 }
7349 else
7350 totems -= 1;
7351 }
7352 if (totems != 0)
7353 return SPELL_FAILED_TOTEMS; //0x7C
7354
7355 // Check items for TotemCategory (items presence in inventory)
7357 for (int i = 0; i < 2; ++i)
7358 {
7359 if (m_spellInfo->TotemCategory[i] != 0)
7360 {
7362 {
7363 TotemCategory -= 1;
7364 continue;
7365 }
7366 }
7367 else
7368 TotemCategory -= 1;
7369 }
7370 if (TotemCategory != 0)
7371 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7372 }
7373
7374 // special checks for spell effects
7375 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7376 {
7377 switch (m_spellInfo->Effects[i].Effect)
7378 {
7381 {
7382 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7383 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7384 if (target->GetTypeId() == TYPEID_PLAYER && !IsTriggered())
7385 {
7386 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7387 // so we need to make sure there is at least one free space in the player's inventory
7389 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7390 {
7391 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7393 }
7394
7395 if (m_spellInfo->Effects[i].ItemType)
7396 {
7397 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7398 if (!itemTemplate)
7400
7401 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7402 ItemPosCountVec dest;
7403 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7404 if (msg != EQUIP_ERR_OK)
7405 {
7407 if (!itemTemplate->ItemLimitCategory)
7408 {
7409 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7411 }
7412 else
7413 {
7414 // Conjure Food/Water/Refreshment spells
7417 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7418 {
7419 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7421 }
7422 else
7423 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7424
7426 }
7427 }
7428 }
7429 }
7430 break;
7431 }
7433 {
7434 if (player->GetFreeInventorySpace() == 0)
7435 {
7436 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7438 }
7439 break;
7440 }
7442 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7444 {
7445 // cannot enchant vellum for other player
7448 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7451 ItemPosCountVec dest;
7452 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7453 if (msg != EQUIP_ERR_OK)
7454 {
7455 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7457 }
7458 }
7459 [[fallthrough]];
7461 {
7462 Item* targetItem = m_targets.GetItemTarget();
7463 if (!targetItem)
7465
7466 // xinef: required level has to be checked also! Exploit fix
7467 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7468 return SPELL_FAILED_LOWLEVEL;
7469
7470 bool isItemUsable = false;
7471 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7472 {
7473 ItemTemplate const* proto = targetItem->GetTemplate();
7474 if (proto->Spells[e].SpellId && (
7477 {
7478 isItemUsable = true;
7479 break;
7480 }
7481 }
7482
7483 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7484 // do not allow adding usable enchantments to items that have use effect already
7485 if (enchantEntry)
7486 {
7487 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7488 {
7489 switch (enchantEntry->type[s])
7490 {
7492 if (isItemUsable)
7494 break;
7496 {
7497 uint32 numSockets = 0;
7498 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7499 if (targetItem->GetTemplate()->Socket[socket].Color)
7500 ++numSockets;
7501
7502 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7504 break;
7505 }
7506 }
7507 }
7508 }
7509
7510 // Not allow enchant in trade slot for some enchant type
7511 if (targetItem->GetOwner() != m_caster)
7512 {
7513 if (!enchantEntry)
7514 return SPELL_FAILED_ERROR;
7515 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7517 }
7518 break;
7519 }
7521 {
7522 Item* item = m_targets.GetItemTarget();
7523 if (!item)
7525 // Not allow enchant in trade slot for some enchant type
7526 if (item->GetOwner() != m_caster)
7527 {
7528 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7529 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7530 if (!pEnchant)
7531 return SPELL_FAILED_ERROR;
7532 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7534 }
7535
7536 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7537 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7538 {
7540 return SPELL_FAILED_LOWLEVEL;
7541 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7543 }
7544
7545 break;
7546 }
7548 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7549 break;
7551 {
7552 if (!m_targets.GetItemTarget())
7554
7555 // prevent disenchanting in trade slot
7558
7559 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7560 if (!itemProto)
7562
7563 uint32 item_quality = itemProto->Quality;
7564 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7565 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7566 if (item_disenchantskilllevel == uint32(-1))
7568 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7570 if (item_quality > 4 || item_quality < 2)
7572 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7574 if (!itemProto->DisenchantID)
7576 break;
7577 }
7579 {
7580 if (!m_targets.GetItemTarget())
7582 //ensure item is a prospectable ore
7585 //prevent prospecting in trade slot
7588 //Check for enough skill in jewelcrafting
7589 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7590 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7592 //make sure the player has the required ores in inventory
7593 if (m_targets.GetItemTarget()->GetCount() < 5)
7595
7598
7599 break;
7600 }
7602 {
7603 if (!m_targets.GetItemTarget())
7605 //ensure item is a millable herb
7608 //prevent milling in trade slot
7611 //Check for enough skill in inscription
7612 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7613 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7615 //make sure the player has the required herbs in inventory
7616 if (m_targets.GetItemTarget()->GetCount() < 5)
7618
7621
7622 break;
7623 }
7626 {
7629
7631 break;
7632
7634 if (!pItem || pItem->IsBroken())
7636
7637 switch (pItem->GetTemplate()->SubClass)
7638 {
7640 {
7641 uint32 ammo = pItem->GetEntry();
7642 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7643 return SPELL_FAILED_NO_AMMO;
7644 };
7645 break;
7649 {
7651 if (!ammo)
7652 {
7653 // Requires No Ammo
7654 if (m_caster->HasAura(46699))
7655 break; // skip other checks
7656
7657 return SPELL_FAILED_NO_AMMO;
7658 }
7659
7660 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7661 if (!ammoProto)
7662 return SPELL_FAILED_NO_AMMO;
7663
7664 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7665 return SPELL_FAILED_NO_AMMO;
7666
7667 // check ammo ws. weapon compatibility
7668 switch (pItem->GetTemplate()->SubClass)
7669 {
7672 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7673 return SPELL_FAILED_NO_AMMO;
7674 break;
7676 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7677 return SPELL_FAILED_NO_AMMO;
7678 break;
7679 default:
7680 return SPELL_FAILED_NO_AMMO;
7681 }
7682
7683 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7684 {
7686 return SPELL_FAILED_NO_AMMO;
7687 }
7688 };
7689 break;
7691 break;
7692 default:
7693 break;
7694 }
7695 break;
7696 }
7698 {
7699 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7700 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7701
7702 if (!pProto)
7704
7705 if (Item* pitem = player->GetItemByEntry(item_id))
7706 {
7707 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7708 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7710 }
7711 break;
7712 }
7713 default:
7714 break;
7715 }
7716 }
7717
7718 // check weapon presence in slots for main/offhand weapons
7719 if (/*never skip those checks !(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7720 {
7721 // main hand weapon required
7723 {
7725
7726 // skip spell if no weapon in slot or broken
7727 if (!item || item->IsBroken())
7729
7730 // skip spell if weapon not fit to triggered spell
7733 }
7734
7735 // offhand hand weapon required
7737 {
7739
7740 // skip spell if no weapon in slot or broken
7741 if (!item || item->IsBroken())
7743
7744 // skip spell if weapon not fit to triggered spell
7747 }
7748
7750 }
7751
7752 return SPELL_CAST_OK;
7753}
std::int8_t int8
Definition: Define.h:106
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
#define MAX_ITEM_SPELLS
Definition: Item.h:209
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:169
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:195
InventoryResult
Definition: Item.h:40
@ EQUIP_ERR_OK
Definition: Item.h:41
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:91
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:371
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:356
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:355
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:372
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:369
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:78
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:88
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:177
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:176
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:166
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:425
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:426
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:623
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:624
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:306
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:304
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:302
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:300
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:772
@ NULL_BAG
Definition: Unit.h:210
@ NULL_SLOT
Definition: Unit.h:211
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:378
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:379
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1598
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1800
@ EFFECT_1
Definition: SharedDefines.h:31
@ MAX_POWERS
Definition: SharedDefines.h:248
@ SPELL_EFFECT_DISENCHANT
Definition: SharedDefines.h:849
@ SPELL_EFFECT_PROSPECTING
Definition: SharedDefines.h:877
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:842
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:803
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:760
@ SPELL_EFFECT_MILLING
Definition: SharedDefines.h:908
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition: SharedDefines.h:816
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:907
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:767
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:780
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition: SharedDefines.h:809
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:906
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:804
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:774
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition: SharedDefines.h:475
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3503
TotemCategory
Definition: SharedDefines.h:3055
@ SPELL_FAILED_CANT_BE_MILLED
Definition: SharedDefines.h:937
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition: SharedDefines.h:952
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition: SharedDefines.h:950
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition: SharedDefines.h:1100
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition: SharedDefines.h:1043
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition: SharedDefines.h:925
@ SPELL_FAILED_NOT_TRADEABLE
Definition: SharedDefines.h:991
@ SPELL_FAILED_ITEM_NOT_READY
Definition: SharedDefines.h:966
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition: SharedDefines.h:997
@ SPELL_FAILED_ITEM_GONE
Definition: SharedDefines.h:964
@ SPELL_FAILED_NO_AMMO
Definition: SharedDefines.h:996
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition: SharedDefines.h:965
@ SPELL_FAILED_EQUIPPED_ITEM
Definition: SharedDefines.h:949
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition: SharedDefines.h:923
@ SPELL_FAILED_ON_USE_ENCHANT
Definition: SharedDefines.h:1091
@ SPELL_FAILED_TOTEMS
Definition: SharedDefines.h:1052
@ SPELL_FAILED_ERROR
Definition: SharedDefines.h:953
@ SPELL_FAILED_REAGENTS
Definition: SharedDefines.h:1021
@ SPELL_FAILED_MAX_SOCKETS
Definition: SharedDefines.h:1105
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition: SharedDefines.h:935
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition: SharedDefines.h:1050
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition: SharedDefines.h:976
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition: SharedDefines.h:938
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition: SharedDefines.h:951
@ SPELL_FAILED_TOTEM_CATEGORY
Definition: SharedDefines.h:1051
@ SKILL_INSCRIPTION
Definition: SharedDefines.h:2974
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2926
@ SKILL_JEWELCRAFTING
Definition: SharedDefines.h:2957
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:295
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:308
bool IsBroken() const
Definition: Item.h:251
bool IsWeaponVellum() const
Definition: Item.h:329
bool IsArmorVellum() const
Definition: Item.h:330
Player * GetOwner() const
Definition: Item.cpp:551
ObjectGuid GetOwnerGUID() const
Definition: Item.h:225
uint32 GetCount() const
Definition: Item.h:263
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:886
int32 SpellCharges
Definition: ItemTemplate.h:602
uint32 SpellTrigger
Definition: ItemTemplate.h:601
int32 SpellId
Definition: ItemTemplate.h:600
uint32 Color
Definition: ItemTemplate.h:611
Definition: ItemTemplate.h:628
uint32 DisenchantID
Definition: ItemTemplate.h:699
uint32 Quality
Definition: ItemTemplate.h:635
uint32 RequiredSkillRank
Definition: ItemTemplate.h:647
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:738
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:671
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:693
uint32 Flags
Definition: ItemTemplate.h:636
uint32 RequiredLevel
Definition: ItemTemplate.h:645
uint32 Class
Definition: ItemTemplate.h:630
uint32 ItemLimitCategory
Definition: ItemTemplate.h:696
uint32 SubClass
Definition: ItemTemplate.h:631
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:690
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:307
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:652
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12229
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:499
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3399
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:688
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:884
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12274
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4054
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1248
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:1643
bool IsFullHealth() const
Definition: Unit.h:1441
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1460
uint32 GetPower(Powers power) const
Definition: Unit.h:1459
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:224
uint32 GetItemTargetEntry() const
Definition: Spell.h:140
ObjectGuid m_castItemGUID
Definition: Spell.h:523
uint32 BaseLevel
Definition: SpellInfo.h:357
uint32 MaxLevel
Definition: SpellInfo.h:356
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:371
flag96 SpellFamilyFlags
Definition: SpellInfo.h:386
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:376
int32 EquippedItemClass
Definition: SpellInfo.h:373
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:370
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:372
Definition: DBCStructure.h:1803
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1806
uint32 slot
Definition: DBCStructure.h:1813

References _triggeredCastFlags, BASE_ATTACK, SpellInfo::BaseLevel, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, ItemTemplate::Flags, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetTypeId(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Object::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, SpellItemEnchantmentEntry::type, and TYPEID_PLAYER.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6824{
6825 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6827
6828 // dead owner (pets still alive when owners ressed?)
6829 if (Unit* owner = m_caster->GetCharmerOrOwner())
6830 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6832
6833 if (!target && m_targets.GetUnitTarget())
6834 target = m_targets.GetUnitTarget();
6835
6837 {
6838 if (!target)
6840 m_targets.SetUnitTarget(target);
6841 }
6842
6843 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6845
6846 // cooldown
6847 if (Creature const* creatureCaster = m_caster->ToCreature())
6848 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6850
6851 // Check if spell is affected by GCD
6855
6856 return CheckCast(true);
6857}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition: Unit.cpp:449
void SetUnitTarget(Unit *target)
Set Unit Target.
Definition: Spell.cpp:270
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2381
uint32 StartRecoveryCategory
Definition: SpellInfo.h:348

References _triggeredCastFlags, SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7143{
7144 // item cast not used power
7145 if (m_CastItem)
7146 return SPELL_CAST_OK;
7147
7148 //While .cheat power is enabled dont check if we need power to cast the spell
7150 {
7152 {
7153 return SPELL_CAST_OK;
7154 }
7155 }
7156
7157 // health as power used - need check health amount
7159 {
7162 return SPELL_CAST_OK;
7163 }
7164 // Check valid power type
7166 {
7167 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7168 return SPELL_FAILED_UNKNOWN;
7169 }
7170
7171 //check rune cost only if a spell has PowerType == POWER_RUNE
7173 {
7175 if (failReason != SPELL_CAST_OK)
7176 return failReason;
7177 }
7178
7179 // Check power amount
7182 return SPELL_FAILED_NO_POWER;
7183 else
7184 return SPELL_CAST_OK;
7185}
@ CHEAT_POWER
Definition: Player.h:994
PowerType
Definition: VehicleDefines.h:30
@ POWER_HEALTH
Definition: SharedDefines.h:250
@ POWER_RUNE
Definition: SharedDefines.h:246
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1006
@ SPELL_FAILED_UNKNOWN
Definition: SharedDefines.h:1108
uint32 GetHealth() const
Definition: Unit.h:1438
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5410
uint32 RuneCostID
Definition: SpellInfo.h:366
uint32 PowerType
Definition: SpellInfo.h:360

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::GetTypeId(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7057{
7058 // Don't check for instant cast spells
7059 if (!strict && m_casttime == 0)
7060 return SPELL_CAST_OK;
7061
7062 uint32 range_type = 0;
7063
7065 {
7066 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7067 // these are triggered by other spells - possibly we should omit range check in that case?
7068 if (m_spellInfo->RangeEntry->ID == 1)
7069 return SPELL_CAST_OK;
7070
7071 range_type = m_spellInfo->RangeEntry->Flags;
7072 }
7073
7074 Unit* target = m_targets.GetUnitTarget();
7075 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7076 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7077
7078 // xinef: hack for npc shooters
7079 if (min_range && GetCaster()->GetTypeId() == TYPEID_UNIT && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7080 range_type = SPELL_RANGE_RANGED;
7081
7082 if (Player* modOwner = m_caster->GetSpellModOwner())
7083 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7084
7085 // xinef: dont check max_range to strictly after cast
7086 if (range_type != SPELL_RANGE_MELEE && !strict)
7087 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7088
7089 if (target)
7090 {
7091 if (target != m_caster)
7092 {
7093 // Xinef: Spells with 5yd range can hit target 9yd away?
7094 if (range_type == SPELL_RANGE_MELEE)
7095 {
7096 float real_max_range = max_range;
7097 if (m_caster->GetTypeId() != TYPEID_UNIT && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking())
7098 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7099 else
7100 real_max_range -= 2 * MIN_MELEE_REACH;
7101
7102 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7104 }
7105 else if (!m_caster->IsWithinCombatRange(target, max_range))
7106 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7107
7109 {
7110 if (m_caster->IsWithinMeleeRange(target))
7112 }
7113
7114 if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
7116 }
7117
7118 // Xinef: check min range for self casts
7119 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7121 }
7122
7123 if (GameObject* goTarget = m_targets.GetGOTarget())
7124 {
7125 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7126 {
7128 }
7129 }
7130
7131 if (m_targets.HasDst() && !m_targets.HasTraj())
7132 {
7133 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7135 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7137 }
7138
7139 return SPELL_CAST_OK;
7140}
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47
@ SPELL_RANGE_MELEE
Definition: Spell.h:89
@ SPELL_RANGE_RANGED
Definition: Spell.h:90
@ SPELLMOD_RANGE
Definition: SpellDefines.h:82
@ SPELL_FACING_FLAG_INFRONT
Definition: SpellDefines.h:126
@ SPELL_FAILED_TOO_CLOSE
Definition: SharedDefines.h:1049
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1018
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition: Object.cpp:1297
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:140
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition: Unit.cpp:840
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15880
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition: Unit.cpp:864
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15860
bool IsWalking() const
Definition: Unit.h:2647
Unit * GetCaster() const
Definition: Spell.h:572
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:367
uint32 FacingCasterFlags
Definition: SpellInfo.h:336
uint32 Flags
Definition: DBCStructure.h:1758
uint32 ID
Definition: DBCStructure.h:1755

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Unit::isMoving(), Unit::IsWalking(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, Object::ToPlayer(), TYPEID_PLAYER, and TYPEID_UNIT.

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5411{
5412 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5413 return SPELL_CAST_OK;
5414
5416 return SPELL_CAST_OK;
5417
5418 Player* player = m_caster->ToPlayer();
5419 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5420 if (player->GetCommandStatus(CHEAT_POWER))
5421 {
5422 return SPELL_CAST_OK;
5423 }
5424
5425 if (player->getClass() != CLASS_DEATH_KNIGHT)
5426 return SPELL_CAST_OK;
5427
5428 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5429
5430 if (!src)
5431 return SPELL_CAST_OK;
5432
5433 if (src->NoRuneCost())
5434 return SPELL_CAST_OK;
5435
5436 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5437
5438 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5439 {
5440 runeCost[i] = src->RuneCost[i];
5441 if (Player* modOwner = m_caster->GetSpellModOwner())
5442 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5443 }
5444
5445 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5446
5447 for (uint32 i = 0; i < MAX_RUNES; ++i)
5448 {
5449 RuneType rune = player->GetCurrentRune(i);
5450 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5451 runeCost[rune]--;
5452 }
5453
5454 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5455 if (runeCost[i] > 0)
5456 runeCost[RUNE_DEATH] += runeCost[i];
5457
5458 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5459 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5460
5461 return SPELL_CAST_OK;
5462}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
RuneType
Definition: Player.h:409
@ RUNE_DEATH
Definition: Player.h:413
@ NUM_RUNE_TYPES
Definition: Player.h:414
#define MAX_RUNES
Definition: Player.h:399
@ SPELLMOD_COST
Definition: SpellDefines.h:91
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:118
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2457
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2456
Definition: DBCStructure.h:1766
uint32 RuneCost[3]
Definition: DBCStructure.h:1768
bool NoRuneCost() const
Definition: DBCStructure.h:1771

References CHEAT_POWER, CLASS_DEATH_KNIGHT, Unit::getClass(), Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellInfo::Id, m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8712{
8713 // Skip if there are not any script
8714 if (!m_loadedScripts.size())
8715 return true;
8716
8717 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8718 {
8719 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8720 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8721 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8722 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8723 return false;
8724
8725 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8726 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8727 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8728 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8729 return false;
8730 }
8731 return true;
8732}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7756{
7757 // check spell focus object
7759 {
7761 Cell cell(p);
7762
7763 GameObject* ok = nullptr;
7766
7768 Map& map = *m_caster->GetMap();
7769 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7770
7771 if (!ok)
7773
7774 focusObject = ok; // game object found in range
7775 }
7776 return SPELL_CAST_OK;
7777}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition: SharedDefines.h:1023
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
Definition: TypeContainer.h:103
Definition: TypeContainerVisitor.h:85
Definition: Cell.h:46
Definition: GridNotifiers.h:316
Definition: GridNotifiers.h:654
Definition: Map.h:312
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.h:867
uint32 RequiresSpellFocus
Definition: SpellInfo.h:335

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition: Spell.h:164
void SetSrc(float x, float y, float z)
Definition: Spell.cpp:413

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2409{
2410 m_UniqueTargetInfo.clear();
2411 m_UniqueGOTargetInfo.clear();
2412 m_UniqueItemInfo.clear();
2413 m_delayMoment = 0;
2415}
uint64 m_delayTrajectory
Definition: Spell.h:639

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7780{
7781 if (!m_caster)// || m_caster->GetTypeId() != TYPEID_PLAYER)
7782 return;
7783
7784 //if (m_spellState == SPELL_STATE_DELAYED)
7785 // return; // spell is active and can't be time-backed
7786
7787 if (isDelayableNoMore()) // Spells may only be delayed twice
7788 return;
7789
7790 // spells not loosing casting time (slam, dynamites, bombs..)
7791 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7792 // return;
7793
7794 //check pushback reduce
7795 int32 delaytime = 500; // spellcasting delay is normally 500ms
7796 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7799 if (delayReduce >= 100)
7800 return;
7801
7802 AddPct(delaytime, -delayReduce);
7803
7804 if (m_timer + delaytime > m_casttime)
7805 {
7806 delaytime = m_casttime - m_timer;
7808 }
7809 else
7810 m_timer += delaytime;
7811
7812 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7813
7814 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7815 data << m_caster->GetPackGUID();
7816 data << uint32(delaytime);
7817
7818 m_caster->SendMessageToSet(&data, true);
7819}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:171
T AddPct(T &base, U pct)
Definition: Util.h:67
@ SPELL_AURA_REDUCE_PUSHBACK
Definition: SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition: SpellDefines.h:86
@ SMSG_SPELL_DELAYED
Definition: Opcodes.h:512
PackedGuid const & GetPackGUID() const
Definition: Object.h:108
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.h:482
T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition: Player.h:2946
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:6666
Definition: WorldPacket.h:27
bool isDelayableNoMore()
Definition: Spell.h:627

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7822{
7824 return;
7825
7826 if (isDelayableNoMore()) // Spells may only be delayed twice
7827 return;
7828
7829 //check pushback reduce
7830 // should be affected by modifiers, not take the dbc duration.
7832
7833 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7834 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7837 if (delayReduce >= 100)
7838 return;
7839
7840 AddPct(delaytime, -delayReduce);
7841
7842 if (m_timer <= delaytime)
7843 {
7844 delaytime = m_timer;
7845 m_timer = 0;
7846 }
7847 else
7848 m_timer -= delaytime;
7849
7850 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7851
7852 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7853 if ((*ihit).missCondition == SPELL_MISS_NONE)
7854 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7855 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7856
7857 // partially interrupt persistent area auras
7859 dynObj->Delay(delaytime);
7860
7862}
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: DynamicObject.h:35
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6884
uint32 getState() const
Definition: Spell.h:482
int32 GetDuration() const
Definition: SpellInfo.cpp:2318

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), Object::GetTypeId(), ObjectAccessor::GetUnit(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, Object::ToPlayer(), and TYPEID_PLAYER.

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
Todo:
Remove magic numbers
8299{
8300 Unit* unit = nullptr;
8301 // In case spell hit target, do all effect on that target
8302 if (targetInfo.missCondition == SPELL_MISS_NONE)
8303 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8304 // In case spell reflect from target, do all effect on caster (if hit)
8305 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8306 unit = m_caster;
8307 if (!unit)
8308 return;
8309
8310 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8311 {
8312 if (targetInfo.effectMask & (1 << i))
8313 {
8314 m_damage = 0;
8315 m_healing = 0;
8316
8317 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8318
8319 if (m_damage > 0)
8320 {
8321 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8322 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8323 {
8326 {
8327 uint32 targetAmount = m_UniqueTargetInfo.size();
8328 if (targetAmount > 10)
8329 m_damage = m_damage * 10 / targetAmount;
8330 }
8331 }
8332 }
8333
8334 if (m_applyMultiplierMask & (1 << i))
8335 {
8337 m_damageMultipliers[i] *= multiplier[i];
8338 }
8339 targetInfo.damage += m_damage;
8340 }
8341 }
8342
8343 // xinef: totem's inherit owner crit chance and dancing rune weapon
8344 Unit* caster = m_caster;
8345 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8346 {
8347 if (Unit* owner = m_caster->GetOwner())
8348 caster = owner;
8349 }
8350 else if (m_originalCaster)
8351 caster = m_originalCaster;
8352
8353 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8354 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8355 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8356}
bool roll_chance_f(float chance)
Definition: Random.h:53
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:12836
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:12761
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, Unit *caster) const
Definition: Unit.cpp:21332
uint32 SchoolMask
Definition: SpellInfo.h:390

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), Object::GetTypeId(), ObjectAccessor::GetUnit(), HandleEffects(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), TargetInfo::targetGUID, and TYPEID_PLAYER.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3356{
3357 if (target->processed) // Check target
3358 return;
3359 target->processed = true; // Target checked in apply effects procedure
3360
3361 uint32 effectMask = target->effectMask;
3362 if (!effectMask)
3363 return;
3364
3365 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3366 if (!go)
3367 return;
3368
3371
3372 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3373 if (effectMask & (1 << effectNumber))
3374 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3375
3376 // xinef: inform ai about spellhit
3378
3380
3382}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:66
GameObjectAI * AI() const
Definition: GameObject.h:1001
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8630
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8643
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8656

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3385{
3386 uint32 effectMask = target->effectMask;
3387 if (!target->item || !effectMask)
3388 return;
3389
3392
3393 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3394 if (effectMask & (1 << effectNumber))
3395 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3396
3398
3400}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2647{
2648 if (!target || target->processed)
2649 return;
2650
2651 target->processed = true; // Target checked in apply effects procedure
2652
2653 // Get mask of effects for target
2654 uint8 mask = target->effectMask;
2655
2656 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2657 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2658 return;
2659
2660 if (!effectUnit || m_spellInfo->Id == 45927)
2661 {
2662 uint8 farMask = 0;
2663 // create far target mask
2664 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2665 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2666 if ((1 << i) & mask)
2667 farMask |= (1 << i);
2668
2669 if (!farMask)
2670 return;
2671 // find unit in world
2672 // Xinef: FindUnit Access without Map check!!! Intended
2673 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2674 if (!effectUnit)
2675 return;
2676
2677 // do far effects on the unit
2678 // can't use default call because of threading, do stuff as fast as possible
2679 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2680 if (farMask & (1 << i))
2681 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2682 return;
2683 }
2684
2685 if (effectUnit->IsAlive() != target->alive)
2686 return;
2687
2688 // Xinef: absorb delayed projectiles for 500ms
2690 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2691 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2692 )
2693 return; // No missinfo in that case
2694
2695 // Get original caster (if exist) and calculate damage/healing from him data
2697
2698 // Skip if m_originalCaster not avaiable
2699 if (!caster)
2700 return;
2701
2702 SpellMissInfo missInfo = target->missCondition;
2703
2704 // Need init unitTarget by default unit (can changed in code on reflect)
2705 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2706 unitTarget = effectUnit;
2707
2708 // Reset damage/healing counter
2709 m_damage = target->damage;
2710 m_healing = -target->damage;
2711
2712 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2713
2716
2717 //Spells with this flag cannot trigger if effect is casted on self
2719 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2720 Unit* spellHitTarget = nullptr;
2721
2722 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2723 spellHitTarget = unitTarget;
2724 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2725 {
2726 missInfo = target->reflectResult;
2727 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2728 {
2729 spellHitTarget = m_caster;
2731 if (m_caster->GetTypeId() == TYPEID_UNIT)
2733 }
2734 }
2735
2736 if (spellHitTarget)
2737 {
2738 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2739 if (missInfo2 != SPELL_MISS_NONE)
2740 {
2741 if (missInfo2 != SPELL_MISS_MISS)
2742 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2743 m_damage = 0;
2744 spellHitTarget = nullptr;
2745
2746 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2747 if (missInfo2 == SPELL_MISS_EVADE)
2748 missInfo = SPELL_MISS_EVADE;
2749 }
2750 }
2751
2752 // Do not take combo points on dodge and miss
2753 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2754 {
2755 m_needComboPoints = false;
2756 // Restore spell mods for a miss/dodge/parry Cold Blood
2758 if (m_caster->GetTypeId() == TYPEID_PLAYER && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2759 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2760 }
2761
2762 // Fill base trigger info
2763 uint32 procAttacker = m_procAttacker;
2764 uint32 procVictim = m_procVictim;
2765 uint32 procEx = m_procEx;
2766
2767 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2768 if (canEffectTrigger && !procAttacker && !procVictim)
2769 {
2770 bool positive = true;
2771 if (m_damage > 0)
2772 positive = false;
2773 else if (!m_healing)
2774 {
2775 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2776 // If at least one effect negative spell is negative hit
2777 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2778 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2779 {
2780 positive = false;
2781 break;
2782 }
2783 }
2784 switch (m_spellInfo->DmgClass)
2785 {
2787 if (positive)
2788 {
2791 }
2792 else
2793 {
2796 }
2797 break;
2799 if (positive)
2800 {
2803 }
2804 else
2805 {
2808 }
2809 break;
2810 }
2811 }
2813
2814 // All calculated do it!
2815 // Do healing and triggers
2816 if (m_healing > 0)
2817 {
2818 bool crit = target->crit;
2819 uint32 addhealth = m_healing;
2820
2821 if (crit)
2822 {
2823 procEx |= PROC_EX_CRITICAL_HIT;
2824 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2825 }
2826 else
2827 procEx |= PROC_EX_NORMAL_HIT;
2828
2829 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2830
2831 // Xinef: override with forced crit, only visual result
2832 if (GetSpellValue()->ForcedCritResult)
2833 {
2834 crit = true;
2835 procEx |= PROC_EX_CRITICAL_HIT;
2836 }
2837
2838 int32 gain = caster->HealBySpell(healInfo, crit);
2839 unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
2840 m_healing = gain;
2841
2842 // Xinef: if heal acutally healed something, add no overheal flag
2843 if (m_healing)
2844 procEx |= PROC_EX_NO_OVERHEAL;
2845
2846 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2847 if (canEffectTrigger)
2848 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2849 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2850 }
2851 // Do damage and triggers
2852 else if (m_damage > 0)
2853 {
2855
2856 // Fill base damage struct (unitTarget - is real spell target)
2858
2859 // Add bonuses and fill damageInfo struct
2860 // Dancing Rune Weapon...
2861 if (m_caster->GetEntry() == 27893)
2862 {
2863 if (Unit* owner = m_caster->GetOwner())
2864 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2865 }
2866 else
2867 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2868
2869 // xinef: override miss info after absorb / block calculations
2870 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2871 {
2872 //if (damageInfo.absorb > 0)
2873 // missInfo = SPELL_MISS_ABSORB;
2874 if (damageInfo.blocked)
2875 missInfo = SPELL_MISS_BLOCK;
2876 }
2877
2878 // Xinef: override with forced crit, only visual result
2879 if (GetSpellValue()->ForcedCritResult)
2880 {
2881 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2882 }
2883
2884 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2885
2886 // xinef: health leech handling
2888 {
2889 uint8 effIndex = EFFECT_0;
2890 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2891 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2892 break;
2893
2894 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2895
2896 // get max possible damage, don't count overkill for heal
2897 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2898
2899 if (m_caster->IsAlive())
2900 {
2901 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2902 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2903
2904 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2905 m_caster->HealBySpell(healInfo);
2906 }
2907 }
2908
2909 // Send log damage message to client
2910 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2911 // Xinef: send info to target about reflect
2912 if (reflectedSpell)
2913 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2914
2915 procEx |= createProcExtendMask(&damageInfo, missInfo);
2916 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2917
2918 caster->DealSpellDamage(&damageInfo, true, this);
2919
2920 // do procs after damage, eg healing effects
2921 // no need to check if target is alive, done in procdamageandspell
2922
2923 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2924 if (canEffectTrigger)
2925 {
2926 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2927 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2928 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2929
2932 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2933 }
2934
2935 m_damage = damageInfo.damage;
2936 }
2937 // Passive spell hits/misses or active spells only misses (only triggers)
2938 else
2939 {
2940 // Fill base damage struct (unitTarget - is real spell target)
2942 procEx |= createProcExtendMask(&damageInfo, missInfo);
2943 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2944 if (canEffectTrigger)
2945 {
2946 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2947 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2948 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2949
2950 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2951 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2955 }
2956
2957 // Failed Pickpocket, reveal rogue
2959 {
2963 }
2964 }
2965
2966 if (m_caster)
2967 {
2969 {
2971
2972 // Unsure if there are more spells that are not supposed to stop enemy from
2973 // regenerating HP from food, so for now it stays as an ID.
2974 const uint32 SPELL_PREMEDITATION = 14183;
2975 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2976 {
2977 if (!effectUnit->IsStandState())
2978 {
2980 }
2981 }
2982 }
2983 }
2984
2985 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2987 {
2988 m_caster->SetInCombatWith(effectUnit);
2989 }
2990
2991 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2993 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2994
2995 if (spellHitTarget)
2996 {
2997 //AI functions
2998 if (spellHitTarget->GetTypeId() == TYPEID_UNIT)
2999 {
3000 if (spellHitTarget->ToCreature()->IsAIEnabled)
3001 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
3002 }
3003
3005 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
3006
3007 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
3008 DoTriggersOnSpellHit(spellHitTarget, mask);
3009
3010 // if target is fallged for pvp also flag caster if a player
3011 // xinef: do not flag spells with aura bind sight (no special attribute)
3012 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
3014 {
3015 m_caster->ToPlayer()->UpdatePvP(true);
3016 }
3017
3019 }
3020}
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition: Unit.cpp:16948
@ UNIT_STAND_STATE_STAND
Definition: Unit.h:53
@ NODAMAGE
Definition: Unit.h:439
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:436
@ HEAL
Definition: Unit.h:438
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition: Spell.h:267
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:54
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
@ PROC_EX_NO_OVERHEAL
Definition: SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:123
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:759
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:401
@ SPELL_ATTR3_SUPRESS_CASTER_PROCS
Definition: SharedDefines.h:481
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition: SharedDefines.h:374
@ SPELL_HIT_TYPE_CRIT
Definition: SharedDefines.h:1508
SpellMissInfo
Definition: SharedDefines.h:1490
@ SPELL_MISS_DODGE
Definition: SharedDefines.h:1494
@ SPELL_MISS_IMMUNE2
Definition: SharedDefines.h:1499
@ SPELL_MISS_RESIST
Definition: SharedDefines.h:1493
@ SPELL_MISS_MISS
Definition: SharedDefines.h:1492
@ SPELL_MISS_BLOCK
Definition: SharedDefines.h:1496
@ SPELL_ATTR4_SUPRESS_WEAPON_PROCS
Definition: SharedDefines.h:525
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:28
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition: CreatureAI.h:139
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: CreatureAI.h:136
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3812
CreatureAI * AI() const
Definition: Creature.h:134
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9669
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7075
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1483
Definition: Unit.h:761
Definition: Unit.h:804
Definition: Unit.h:908
uint32 m_lastSanctuaryTime
Definition: Unit.h:2396
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition: Unit.cpp:1801
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:7201
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition: Unit.cpp:7034
bool CanProc()
Definition: Unit.h:2588
bool IsPvP() const
Definition: Unit.h:1515
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:13219
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:14341
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition: Unit.cpp:12046
bool IsStandState() const
Definition: Unit.cpp:17662
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:2408
int32 GetHealthGain(int32 dVal)
Definition: Unit.cpp:14869
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:13088
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:7066
bool IsAIEnabled
Definition: Unit.h:2618
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition: Unit.h:1592
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:13330
void SetStandState(uint8 state)
Definition: Unit.cpp:17668
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5919
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:1046
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition: Unit.cpp:1663
ObjectGuid GetUnitTargetGUID() const
Definition: Spell.cpp:237
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition: Spell.cpp:8734
SpellValue const * GetSpellValue()
Definition: Spell.h:582
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition: Spell.cpp:3022
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition: Spell.cpp:3278
uint32 AttributesEx3
Definition: SpellInfo.h:325
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1008
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1225

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), Object::GetTypeId(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_CASTER_PROCS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR4_SUPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1658{
1659 if (!unitTarget)
1660 return;
1661
1662 Player* player = unitTarget->ToPlayer();
1663 if (!player)
1664 {
1665 return;
1666 }
1667
1668 uint32 newitemid = itemId;
1669
1670 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1671 if (!pProto)
1672 {
1673 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1674 return;
1675 }
1676
1677 uint32 addNumber = damage;
1678
1679 // bg reward have some special in code work
1680 bool SelfCast = true;
1681 switch (m_spellInfo->Id)
1682 {
1687 case SPELL_WS_MARK_TIE:
1690 SelfCast = true;
1691 break;
1693 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1694 addNumber = 3;
1695 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1696 addNumber = 2;
1697 else
1698 addNumber = 1;
1699 SelfCast = true;
1700 break;
1701 }
1702
1703 if (addNumber < 1)
1704 addNumber = 1;
1705 if (addNumber > pProto->GetMaxStackSize())
1706 addNumber = pProto->GetMaxStackSize();
1707
1708 /* == gem perfection handling == */
1709
1710 // the chance of getting a perfect result
1711 float perfectCreateChance = 0.0f;
1712
1713 // the resulting perfect item if successful
1714 uint32 perfectItemType = itemId;
1715
1716 // get perfection capability and chance
1717 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1718 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1719 newitemid = perfectItemType; // the perfect item replaces the regular one
1720
1721 /* == gem perfection handling over == */
1722
1723 /* == profession specialization handling == */
1724
1725 // init items_count to 1, since 1 item will be created regardless of specialization
1726 int32 itemsCount = 1;
1727 float additionalCreateChance = 0.0f;
1728 int32 additionalMaxNum = 0;
1729 // get the chance and maximum number for creating extra items
1730 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1731 {
1732 // roll with this chance till we roll not to create or we create the max num
1733 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1734 ++itemsCount;
1735 }
1736
1737 // really will be created more items
1738 addNumber *= itemsCount;
1739
1740 /* == profession specialization handling over == */
1741
1742 // can the player store the new item?
1743 ItemPosCountVec dest;
1744 uint32 no_space = 0;
1745 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1746 if (msg != EQUIP_ERR_OK)
1747 {
1748 // convert to possible store amount
1750 addNumber -= no_space;
1751 else
1752 {
1753 // if not created by another reason from full inventory or unique items amount limitation
1754 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1755 return;
1756 }
1757 }
1758
1759 if (addNumber)
1760 {
1761 // create the new item and store it
1762 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1763
1764 // was it successful? return error if not
1765 if (!pItem)
1766 {
1767 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1768 return;
1769 }
1770
1771 // set the "Crafted by ..." property of the item
1772 if (pItem->GetTemplate()->HasSignature())
1773 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1774
1775 // send info to the client
1776 player->SendNewItem(pItem, addNumber, true, SelfCast);
1777
1778 sScriptMgr->OnCreateItem(player, pItem, addNumber);
1779
1780 // we succeeded in creating at least one item, so a levelup is possible
1781 if (SelfCast)
1783 }
1784}
@ SPELL_WS_MARK_WINNER
Definition: Battleground.h:101
@ SPELL_AV_MARK_LOSER
Definition: Battleground.h:105
@ SPELL_WS_MARK_TIE
Definition: Battleground.h:102
@ SPELL_WS_MARK_LOSER
Definition: Battleground.h:100
@ SPELL_AB_MARK_LOSER
Definition: Battleground.h:103
@ SPELL_WG_MARK_WINNER
Definition: Battleground.h:109
@ SPELL_AB_MARK_WINNER
Definition: Battleground.h:104
@ SPELL_AV_MARK_WINNER
Definition: Battleground.h:106
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:64
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:58
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition: SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition: SkillExtraItems.cpp:202
bool HasSignature() const
Definition: ItemTemplate.h:707
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:725
bool UpdateCraftSkill(uint32 spellid)
Definition: PlayerUpdates.cpp:785
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4781
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2554

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, ITEM_FIELD_CREATOR, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
3023{
3024 if (!unit || !effectMask)
3025 return SPELL_MISS_EVADE;
3026
3027 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3028 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3029 {
3030 return SPELL_MISS_IMMUNE;
3031 }
3032
3033 // disable effects to which unit is immune
3034 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3035 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3036 {
3037 if (effectMask & (1 << effectNumber))
3038 {
3039 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3040 effectMask &= ~(1 << effectNumber);
3041 // Xinef: Buggs out polymorph
3042 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3043 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3044 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3045 {
3046 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3047 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3048
3049 if (debuff_resist_chance > 0)
3050 if (irand(0,10000) <= (debuff_resist_chance * 100))
3051 {
3052 effectMask &= ~(1 << effectNumber);
3053 returnVal = SPELL_MISS_RESIST;
3054 }
3055 }*/
3056 }
3057 }
3058 if (!effectMask)
3059 return returnVal;
3060
3061 if (unit->GetTypeId() == TYPEID_PLAYER)
3062 {
3066 }
3067
3069 {
3072 }
3073
3074 if (m_caster != unit)
3075 {
3076 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3077 // Xinef: Also check evade state
3078 if (m_spellInfo->Speed > 0.0f)
3079 {
3080 if (unit->GetTypeId() == TYPEID_UNIT && unit->ToCreature()->IsInEvadeMode())
3081 return SPELL_MISS_EVADE;
3082
3084 return SPELL_MISS_EVADE;
3085 }
3086
3087 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3088 {
3090 }
3091 else if (m_caster->IsFriendlyTo(unit))
3092 {
3093 // for delayed spells ignore negative spells (after duel end) for friendly targets
3095 if(!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->IsPositive())
3096 return SPELL_MISS_EVADE;
3097
3098 // assisting case, healing and resurrection
3100 {
3103 m_caster->ToPlayer()->UpdatePvP(true);
3104 }
3105
3106 // xinef: triggered spells should not prolong combat
3108 {
3109 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3110 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3111 }
3112 }
3113 }
3114
3115 uint8 aura_effmask = 0;
3116 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3117 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3118 aura_effmask |= 1 << i;
3119
3120 Unit* originalCaster = GetOriginalCaster();
3121 if (!originalCaster)
3122 originalCaster = m_caster;
3123
3124 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3125 // Xinef: Do not increase diminishing level for self cast
3127 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3129 {
3132
3133 uint32 flagsExtra = unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3134
3135 // Increase Diminishing on unit, current informations for actually casts will use values above
3136 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3138 {
3139 // Do not apply diminish return if caster is NPC
3141 {
3143 }
3144 }
3145 }
3146
3148 {
3150 }
3151
3152 if (aura_effmask)
3153 {
3154 // Select rank for aura with level requirements only in specific cases
3155 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3156 SpellInfo const* aurSpellInfo = m_spellInfo;
3157 int32 basePoints[3];
3158 if (scaleAura)
3159 {
3161 ASSERT(aurSpellInfo);
3162 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3163 {
3164 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3165 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3166 {
3167 aurSpellInfo = m_spellInfo;
3168 break;
3169 }
3170 }
3171 }
3172
3173 if (m_originalCaster)
3174 {
3175 bool refresh = false;
3176 bool refreshPeriodic = m_spellInfo->StackAmount < 2 && !(_triggeredCastFlags & TRIGGERED_NO_PERIODIC_RESET);
3177 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3178 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3179
3180 // xinef: if aura was not refreshed, add proc ex
3181 if (!refresh)
3183
3184 if (m_spellAura)
3185 {
3186 // Set aura stack amount to desired value
3188 {
3189 if (!refresh)
3191 else
3193 }
3194
3195 // Now Reduce spell duration using data received at spell hit
3196 int32 duration = m_spellAura->GetMaxDuration();
3197 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3198
3199 // Xinef: if unit == caster - test versus original unit if available
3200 float diminishMod = 1.0f;
3201 if (unit == m_caster && m_targets.GetUnitTarget())
3203 else
3204 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3205
3206 // unit is immune to aura if it was diminished to 0 duration
3207 if (diminishMod == 0.0f)
3208 {
3210 bool found = false;
3211 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3212 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3213 found = true;
3214 if (!found)
3215 return SPELL_MISS_IMMUNE;
3216 }
3217 else
3218 {
3219 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3220
3221 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3223 positive = aurApp->IsPositive();
3224
3225 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3226
3227 // xinef: haste affects duration of those spells twice
3230
3231 if (m_spellValue->AuraDuration != 0)
3232 {
3233 if (m_spellAura->GetMaxDuration() != -1)
3234 {
3236 }
3237
3239 }
3240 else if (duration != m_spellAura->GetMaxDuration())
3241 {
3242 m_spellAura->SetMaxDuration(duration);
3243 m_spellAura->SetDuration(duration);
3244 }
3245
3246 // xinef: apply relic cooldown, imo best place to add this
3249
3252 }
3253 }
3254 }
3255 }
3256
3257 int8 sanct_effect = -1;
3258
3259 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3260 {
3261 // handle sanctuary effects after aura apply!
3262 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3263 {
3264 sanct_effect = effectNumber;
3265 continue;
3266 }
3267
3268 if (effectMask & (1 << effectNumber))
3269 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3270 }
3271
3272 if( sanct_effect >= 0 && (effectMask & (1 << sanct_effect)) )
3273 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3274
3275 return SPELL_MISS_NONE;
3276}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:68
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:69
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ UNIT_STATE_ATTACK_PLAYER
Definition: Unit.h:339
@ UNIT_FLAG_NON_ATTACKABLE
Definition: Unit.h:449
@ SPELL_AURA_PERIODIC_HASTE
Definition: SpellAuraDefines.h:379
@ SPELL_AURA_REFLECT_SPELLS
Definition: SpellAuraDefines.h:91
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:44
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:150
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition: SpellMgr.cpp:276
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition: SpellMgr.cpp:59
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:246
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:118
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:119
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:187
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:148
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:223
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3248
@ SPELL_EFFECT_SANCTUARY
Definition: SharedDefines.h:829
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:552
DiminishingReturnsType
Definition: SharedDefines.h:3221
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3223
@ DRTYPE_ALL
Definition: SharedDefines.h:3224
bool isWorldBoss() const
Definition: Creature.h:114
bool IsInEvadeMode() const
Definition: Creature.h:128
uint32 flags_extra
Definition: CreatureData.h:239
float GetFloatValue(uint16 index) const
Definition: Object.cpp:319
static ObjectGuid const Empty
Definition: ObjectGuid.h:122
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:6494
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:15720
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:15746
uint32 GetCombatTimer() const
Definition: Unit.h:1734
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:13592
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:18165
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:1478
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:15760
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:15586
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:2688
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:14483
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:2054
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:6461
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:13507
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:13676
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:11053
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:14626
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:2046
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:1011
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2753
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1037
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:328
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:884
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:217
uint8 AuraStackAmount
Definition: Spell.h:216
Unit * GetOriginalCaster() const
Definition: Spell.h:573
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2506

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), _triggeredCastFlags, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::getLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraType(), Unit::HasAuraTypeWithAffectMask(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_AURA_REFLECT_SPELLS, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3279{
3280 // Apply additional spell effects to target
3282 if (m_preCastSpell)
3283 {
3284 // Paladin immunity shields
3285 if (m_preCastSpell == 61988)
3286 {
3287 // Cast Forbearance
3288 m_caster->CastSpell(unit, 25771, true);
3289 // Cast Avenging Wrath Marker
3290 unit->CastSpell(unit, 61987, true);
3291 }
3292
3293 // Avenging Wrath
3294 if (m_preCastSpell == 61987)
3295 // Cast the serverside immunity shield marker
3296 m_caster->CastSpell(unit, 61988, true);
3297
3298 // Fearie Fire (Feral) - damage
3299 if( m_preCastSpell == 60089 )
3300 m_caster->CastSpell(unit, m_preCastSpell, true);
3301 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3302 // Blizz seems to just apply aura without bothering to cast
3304 }
3305
3306 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3307 // this is executed after spell proc spells on target hit
3308 // spells are triggered for each hit spell target
3309 // info confirmed with retail sniffs of permafrost and shadow weaving
3310 if (!m_hitTriggerSpells.empty())
3311 {
3312 int _duration = 0;
3313 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3314 {
3315 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3316 {
3317 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3318 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3319
3320 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3321 // set duration of current aura to the triggered spell
3322 if (i->triggeredSpell->GetDuration() == -1)
3323 {
3324 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3325 {
3326 // get duration from aura-only once
3327 if (!_duration)
3328 {
3329 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3330 _duration = aur ? aur->GetDuration() : -1;
3331 }
3332 triggeredAur->SetDuration(_duration);
3333 }
3334 }
3335 }
3336 }
3337 }
3338
3339 // trigger linked auras remove/apply
3341 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3342 {
3343 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3344 if (*i < 0)
3345 {
3346 unit->RemoveAurasDueToSpell(-(*i));
3347 }
3348 else
3349 {
3350 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3351 }
3352 }
3353}
bool roll_chance_i(int chance)
Definition: Random.h:59
@ SPELL_LINK_HIT
Definition: SpellMgr.h:97
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:6343
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:19751
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:753

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4288{
4290 return;
4291
4292 if (!gameObjTarget)
4293 return;
4294
4295 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4296 switch (action)
4297 {
4298 case GameObjectActions::AnimateCustom0:
4299 case GameObjectActions::AnimateCustom1:
4300 case GameObjectActions::AnimateCustom2:
4301 case GameObjectActions::AnimateCustom3:
4302 gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
4303 break;
4304 case GameObjectActions::Disturb: // What's the difference with Open?
4305 case GameObjectActions::Open:
4306 if (Unit* unitCaster = m_caster->ToUnit())
4307 gameObjTarget->Use(unitCaster);
4308 break;
4309 case GameObjectActions::OpenAndUnlock:
4310 if (Unit* unitCaster = m_caster->ToUnit())
4311 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4312 [[fallthrough]];
4313 case GameObjectActions::Unlock:
4314 case GameObjectActions::Lock:
4315 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
4316 break;
4317 case GameObjectActions::Close:
4318 case GameObjectActions::Rebuild:
4320 break;
4321 case GameObjectActions::Despawn:
4323 break;
4324 case GameObjectActions::MakeInert:
4325 case GameObjectActions::MakeActive:
4326 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
4327 break;
4328 case GameObjectActions::CloseAndLock:
4331 break;
4332 case GameObjectActions::Destroy:
4333 if (Unit* unitCaster = m_caster->ToUnit())
4334 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4335 break;
4336 case GameObjectActions::UseArtKit0:
4337 case GameObjectActions::UseArtKit1:
4338 case GameObjectActions::UseArtKit2:
4339 case GameObjectActions::UseArtKit3:
4340 {
4341 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4342
4343 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4344
4345 uint32 artKitValue = 0;
4346 if (templateAddon)
4347 artKitValue = templateAddon->artKits[artKitIndex];
4348
4349 if (artKitValue == 0)
4350 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4351 else
4352 gameObjTarget->SetGoArtKit(artKitValue);
4353
4354 break;
4355 }
4356 case GameObjectActions::None:
4357 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4358 break;
4359 default:
4360 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4361 break;
4362 }
4363}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:155
GameObjectActions
Definition: GameObject.h:742
@ GAMEOBJECT_FLAGS
Definition: UpdateFields.h:399
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1579
@ GO_FLAG_LOCKED
Definition: SharedDefines.h:1576
Definition: GameObject.h:674
std::array< uint32, 4 > artKits
Definition: GameObject.h:680
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1400
void SetGoArtKit(uint8 artkit)
Definition: GameObject.cpp:1414
void SendCustomAnim(uint32 anim)
Definition: GameObject.cpp:2119
void ResetDoorOrButton()
Definition: GameObject.cpp:1390
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition: GameObject.cpp:903
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition: GameObject.cpp:882
void Use(Unit *user)
Definition: GameObject.cpp:1450
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:847
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:901

References Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, GameObject::DespawnOrUnsummon(), effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), GameObject::Use(), and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5824{
5826 return;
5827
5829 return;
5830
5831 Player* player = m_caster->ToPlayer();
5832
5833 if (player->getClass() != CLASS_DEATH_KNIGHT)
5834 return;
5835
5836 // needed later
5838
5839 uint32 count = damage;
5840 if (count == 0) count = 1;
5841 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5842 {
5843 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5844 {
5845 if (m_spellInfo->Id == 45529)
5846 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5847 continue;
5848 player->SetRuneCooldown(j, 0);
5849 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5850 --count;
5851 }
5852 }
5853
5854 // Blood Tap
5855 if (m_spellInfo->Id == 45529 && count > 0)
5856 {
5857 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5858 {
5859 // Check if both runes are on cd as that is the only time when this needs to come into effect
5860 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5861 {
5862 // Should always update the rune with the lowest cd
5863 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5864 l++;
5865 player->SetRuneCooldown(l, 0);
5866 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5867 --count;
5868 }
5869 else
5870 break;
5871 }
5872 }
5873
5874 // Empower rune weapon
5875 if (m_spellInfo->Id == 47568)
5876 {
5877 // Need to do this just once
5878 if (effIndex != 0)
5879 return;
5880
5881 for (uint32 i = 0; i < MAX_RUNES; ++i)
5882 {
5883 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5884 {
5885 player->SetRuneCooldown(i, 0);
5886 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5887 }
5888 }
5889 }
5890
5891 // is needed to push through to the client that the rune is active
5892 //player->ResyncRunes(MAX_RUNES);
5893 m_caster->CastSpell(m_caster, 47804, true);
5894}
@ RUNE_FROST
Definition: Player.h:412
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition: Player.h:2465
uint8 GetRunesState() const
Definition: Player.h:2454
void SetGracePeriod(uint8 index, uint32 period)
Definition: Player.h:2466
RuneType GetBaseRune(uint8 index) const
Definition: Player.h:2455

References Unit::CastSpell(), CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Unit::getClass(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), Object::GetTypeId(), SpellInfo::Id, Unit::IsInCombat(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6216{
6218 return;
6219
6220 if (!unitTarget)
6221 return;
6222
6223 Player* player = unitTarget->ToPlayer();
6224 if (!player)
6225 {
6226 return;
6227 }
6228
6229 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6230}
void ActivateSpec(uint8 spec)
Definition: Player.cpp:14763

References Player::ActivateSpec(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4125{
4127 {
4128 return;
4129 }
4130
4131 if (!unitTarget || damage <= 0)
4132 {
4133 return;
4134 }
4135
4137}
void AddComboPointGain(Unit *target, int8 amount)
Definition: Spell.h:530

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4699{
4701 {
4702 return;
4703 }
4704
4705 if (!unitTarget || !unitTarget->IsAlive())
4706 {
4707 return;
4708 }
4709
4711
4713}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:3149
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5118

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2733{
2735 return;
2736
2738 return;
2739
2740 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2741 int32 duration = m_spellInfo->GetDuration();
2742 // Caster not in world, might be spell triggered from aura removal
2743 if (!m_caster->IsInWorld())
2744 return;
2745
2746 // Remove old farsight if exist
2747 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2748
2749 DynamicObject* dynObj = new DynamicObject(true);
2750 if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
2751 {
2752 delete dynObj;
2753 return;
2754 }
2755
2756 dynObj->SetDuration(duration);
2757 dynObj->SetCasterViewpoint(updateViewerVisibility);
2758}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition: DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition: DynamicObject.cpp:207
void SetCasterViewpoint(bool updateViewerVisibility)
Definition: DynamicObject.cpp:235
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition: DynamicObject.cpp:101
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:632

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), Object::GetTypeId(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), SPELL_EFFECT_HANDLE_HIT, and TYPEID_PLAYER.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2803{
2805 return;
2806
2808 return;
2809
2810 // not scale value for item based reward (/10 value expected)
2811 if (m_CastItem)
2812 {
2813 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2814 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2816 return;
2817 }
2818
2819 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2820 if (damage <= 50)
2821 {
2823 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2824 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2825 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2826 }
2827 else
2828 {
2829 //maybe we have correct honor_gain in damage already
2830 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2831 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2833 }
2834}
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:33
std::string ToString() const
Definition: ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition: Player.cpp:5953

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::getLevel(), Object::GetTypeId(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), TYPEID_PLAYER, and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1330{
1332 return;
1333
1334 if (!m_spellAura || !unitTarget)
1335 return;
1338}
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition: SpellAuras.cpp:751

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4366{
4368 return;
4369
4371 return;
4372
4373 Player* player = m_caster->ToPlayer();
4374
4375 // glyph sockets level requirement
4376 uint8 minLevel = 0;
4377 switch (m_glyphIndex)
4378 {
4379 case 0:
4380 case 1:
4381 minLevel = 15;
4382 break;
4383 case 2:
4384 minLevel = 50;
4385 break;
4386 case 3:
4387 minLevel = 30;
4388 break;
4389 case 4:
4390 minLevel = 70;
4391 break;
4392 case 5:
4393 minLevel = 80;
4394 break;
4395 }
4396 if (minLevel && m_caster->getLevel() < minLevel)
4397 {
4399 return;
4400 }
4401
4402 // apply new one
4403 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4404 {
4405 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4406 {
4407 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4408 {
4409 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4410 {
4412 return; // glyph slot mismatch
4413 }
4414 }
4415
4416 // remove old glyph aura
4417 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4418 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4419 {
4420 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4421
4422 // Removed any triggered auras
4423 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4424 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4425 {
4426 Aura* aura = iter->second;
4427 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4428 {
4429 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4430 {
4431 player->RemoveOwnedAura(iter);
4432 continue;
4433 }
4434 }
4435 ++iter;
4436 }
4437
4438 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4439 }
4440
4441 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4443 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4444 player->SendTalentsInfoData(false);
4445 }
4446 }
4447}
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:148
#define MAX_GLYPH_SLOT_INDEX
Definition: SharedDefines.h:648
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition: SharedDefines.h:1098
@ SPELL_FAILED_INVALID_GLYPH
Definition: SharedDefines.h:1096
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14115
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:2972
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1720
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1711
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1712
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
All aura base removes should go through this function!
Definition: Unit.cpp:5346
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:1295
AuraMap & GetOwnedAuras()
Definition: Unit.h:2142
bool PlayerLoading() const
Definition: WorldSession.h:335
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2767
Definition: DBCStructure.h:1020

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::getLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::GetTypeId(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_SHAPESHIFT, and TYPEID_PLAYER.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6352{
6354 return;
6355
6356 if (!unitTarget)
6357 return;
6358
6359 Player* player = unitTarget->ToPlayer();
6360 if (!player)
6361 {
6362 return;
6363 }
6364
6365 WorldLocation homeLoc;
6366 uint32 areaId = player->GetAreaId();
6367
6368 if (m_spellInfo->Effects[effIndex].MiscValue)
6369 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6370
6371 if (m_targets.HasDst())
6372 homeLoc.WorldRelocate(*destTarget);
6373 else
6374 {
6375 homeLoc = player->GetWorldLocation();
6376 }
6377
6378 player->SetHomebind(homeLoc, areaId);
6379
6380 // binding
6381 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6382 data << float(homeLoc.GetPositionX());
6383 data << float(homeLoc.GetPositionY());
6384 data << float(homeLoc.GetPositionZ());
6385 data << uint32(homeLoc.GetMapId());
6386 data << uint32(areaId);
6387 player->SendDirectMessage(&data);
6388
6389 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6390 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6391 // zone update
6392 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6393 data << m_caster->GetGUID();
6394 data << uint32(areaId);
6395 player->SendDirectMessage(&data);
6396}
@ SMSG_BINDPOINTUPDATE
Definition: Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition: Opcodes.h:374
Definition: Position.h:251
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:259
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition: Position.h:281
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:5580
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4927

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4725{
4727 return;
4728
4730 m_caster->ToPlayer()->SetCanBlock(true);
4731}
void SetCanBlock(bool value)
Definition: Player.cpp:12845

References effectHandleMode, Object::GetTypeId(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6279{
6281 return;
6282
6284 return;
6285
6286 Player* p_caster = m_caster->ToPlayer();
6287 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6288 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6289
6290 for (; n_buttons; --n_buttons, ++button_id)
6291 {
6292 ActionButton const* ab = p_caster->GetActionButton(button_id);
6293 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6294 continue;
6295
6298 uint32 spell_id = ab->GetAction();
6299 if (!spell_id)
6300 continue;
6301
6302 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6303 if (!spellInfo)
6304 continue;
6305
6306 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6307 continue;
6308
6310 continue;
6311
6312 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6313 if (m_caster->GetPower(POWER_MANA) < cost)
6314 continue;
6315
6317 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6318 }
6319}
@ ACTION_BUTTON_SPELL
Definition: Player.h:230
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:618
Definition: Player.h:254
uint32 GetAction() const
Definition: Player.h:262
ActionButtonType GetType() const
Definition: Player.h:261
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5541
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3812

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), Object::GetTypeId(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_GCD, and TYPEID_PLAYER.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4944{
4946 {
4947 if (!unitTarget)
4948 return;
4949
4951 {
4952 sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true);
4953 }
4954
4955 // charge changes fall time
4956 if( m_caster->GetTypeId() == TYPEID_PLAYER )
4958
4959 ObjectGuid targetGUID = ObjectGuid::Empty;
4961 {
4962 targetGUID = unitTarget->GetGUID();
4963 }
4964
4965 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4966 // Spell is not using explicit target - no generated path
4967 if (!m_preGeneratedPath)
4968 {
4970 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4971
4973 {
4974 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
4975 }
4976 }
4977 else
4978 {
4979 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4980
4982 {
4983 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
4984 }
4985 }
4986 }
4987
4989 {
4990 sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true);
4991 }
4992}
#define SPEED_CHARGE
Definition: MotionMaster.h:107
@ EVENT_CHARGE
Definition: SharedDefines.h:3283
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition: Object.cpp:2769
Definition: Position.h:28
float m_positionZ
Definition: Position.h:58
float GetRelativeAngle(const Position *pos) const
Definition: Position.h:197
float m_positionX
Definition: Position.h:56
float m_positionY
Definition: Position.h:57
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2284
MotionMaster * GetMotionMaster()
Definition: Unit.h:2530
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
Definition: MotionMaster.cpp:586

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), Object::GetTypeId(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1787{
1789 return;
1790
1791 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1792 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1793}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5146
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition: SpellEffects.cpp:1657

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1796{
1798 return;
1799
1800 if (!unitTarget)
1801 return;
1802
1803 Player* player = unitTarget->ToPlayer();
1804 if (!player)
1805 {
1806 return;
1807 }
1808
1809 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1810
1811 if (itemId)
1812 DoCreateItem(effIndex, itemId);
1813
1814 // special case: fake item replaced by generate using spell_loot_template
1816 {
1817 if (itemId)
1818 {
1819 if (!player->HasItemCount(itemId))
1820 return;
1821
1822 // remove reagent
1823 uint32 count = 1;
1824 player->DestroyItemCount(itemId, count, true);
1825
1826 // create some random items
1828 }
1829 else
1830 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1831 }
1833}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition: Player.cpp:13195
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3151
bool IsLootCrafting() const
Definition: SpellInfo.cpp:908

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1836{
1838 return;
1839
1840 if (!unitTarget)
1841 return;
1842
1843 Player* player = unitTarget->ToPlayer();
1844 if (!player)
1845 {
1846 return;
1847 }
1848
1849 // create some random items
1852}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5897{
5899 return;
5900
5902 return;
5903
5904 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5905 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5906 if (!pet)
5907 return;
5908
5909 // add to world
5910 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5911
5912 // unitTarget has pet now
5913 unitTarget->SetMinion(pet, true);
5914
5915 pet->InitTalentForLevel();
5916
5918 {
5921 }
5922}
@ CLASS_HUNTER
Definition: SharedDefines.h:115
void InitTalentForLevel()
Definition: Pet.cpp:2167
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:494
void PetSpellInitialize()
Definition: Player.cpp:9333
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:11484
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:18257
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:557

References Map::AddToMap(), CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, Unit::getClass(), WorldObject::GetMap(), Unit::GetPetGUID(), Object::GetTypeId(), SpellInfo::Id, Pet::InitTalentForLevel(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5299{
5301 return;
5302
5303 int32 mana = 0;
5304 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5305 {
5306 if (!m_caster->m_SummonSlot[slot])
5307 continue;
5308
5310 if (totem && totem->IsTotem())
5311 {
5312 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5313 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5314 if (spellInfo)
5315 {
5316 mana += spellInfo->ManaCost;
5318 }
5319 totem->ToTotem()->UnSummon();
5320 }
5321 }
5322 ApplyPct(mana, damage);
5323 if (mana)
5324 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5325}
T ApplyPct(T &base, U pct)
Definition: Util.h:73
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:1211
#define MAX_TOTEM_SLOT
Definition: Unit.h:1212
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:108
Totem * ToTotem()
Definition: Unit.h:2667
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1521
uint32 GetCreateMana() const
Definition: Unit.h:2285
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:2318
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3290
uint32 ManaCostPercentage
Definition: SpellInfo.h:365
uint32 ManaCost
Definition: SpellInfo.h:361

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5925{
5927 return;
5928
5929 if (!unitTarget)
5930 return;
5931
5932 Player* player = unitTarget->ToPlayer();
5933 if (!player)
5934 {
5935 return;
5936 }
5937
5938 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5939 if (sTaxiNodesStore.LookupEntry(nodeid))
5940 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5941}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:160

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4503{
4505 return;
4506
4508 return;
4509
4510 if (Player* caster = m_caster->ToPlayer())
4511 {
4512 caster->UpdateCraftSkill(m_spellInfo->Id);
4513 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4514 }
4515
4516 // item will be removed at disenchanting end
4517}
@ LOOT_DISENCHANTING
Definition: LootMgr.h:84

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4581{
4583 return;
4584
4585 if (!unitTarget || !unitTarget->IsPet())
4586 return;
4587
4588 Pet* pet = unitTarget->ToPet();
4589
4590 ExecuteLogEffectUnsummonObject(effIndex, pet);
4592}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:872
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5164

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2573{
2575 return;
2576
2577 if (!unitTarget)
2578 return;
2579
2580 // Create dispel mask by dispel type
2581 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2582 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2583
2584 DispelChargesList dispel_list;
2585 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list);
2586 if (dispel_list.empty())
2587 return;
2588
2589 // Ok if exist some buffs for dispel try dispel it
2590 uint32 failCount = 0;
2591 DispelChargesList success_list;
2592 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2593 // dispel N = damage buffs (or while exist buffs for dispel)
2594 for (int32 count = 0; count < damage && !dispel_list.empty();)
2595 {
2596 // Random select buff for dispel
2597 DispelChargesList::iterator itr = dispel_list.begin();
2598 std::advance(itr, urand(0, dispel_list.size() - 1));
2599
2600 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2601 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2602 if (!chance)
2603 {
2604 dispel_list.erase(itr);
2605 continue;
2606 }
2607 else
2608 {
2609 if (roll_chance_i(chance))
2610 {
2611 bool alreadyListed = false;
2612 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2613 {
2614 if (successItr->first->GetId() == itr->first->GetId())
2615 {
2616 ++successItr->second;
2617 alreadyListed = true;
2618 }
2619 }
2620 if (!alreadyListed)
2621 success_list.push_back(std::make_pair(itr->first, 1));
2622 --itr->second;
2623 if (itr->second <= 0)
2624 dispel_list.erase(itr);
2625 }
2626 else
2627 {
2628 if (!failCount)
2629 {
2630 // Failed to dispell
2631 dataFail << m_caster->GetGUID(); // Caster GUID
2632 dataFail << unitTarget->GetGUID(); // Victim GUID
2633 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2634 }
2635 ++failCount;
2636 dataFail << uint32(itr->first->GetId()); // Spell Id
2637 }
2638 ++count;
2639 }
2640 }
2641
2642 if (failCount)
2643 m_caster->SendMessageToSet(&dataFail, true);
2644
2645 // put in combat
2648
2649 if (success_list.empty())
2650 return;
2651
2652 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2653 // Send packet header
2654 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2655 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2656 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2657 dataSuccess << uint8(0); // not used
2658 dataSuccess << uint32(success_list.size()); // count
2659 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2660 {
2661 // Send dispelled spell info
2662 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2663 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2664 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2665 }
2666 m_caster->SendMessageToSet(&dataSuccess, true);
2667
2668 // On success dispel
2669 // Devour Magic
2671 {
2672 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2673 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2674 // Glyph of Felhunter
2675 if (Unit* owner = m_caster->GetOwner())
2676 if (owner->GetAura(56249))
2677 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2678 }
2679}
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition: SpellMgr.h:40
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3505
@ SMSG_DISPEL_FAILED
Definition: Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition: Opcodes.h:665
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition: Unit.cpp:5664
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList)
Definition: Unit.cpp:6367
uint32 GetCategory() const
Definition: SpellInfo.cpp:863

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5204{
5206 return;
5207
5208 if (!unitTarget)
5209 return;
5210
5211 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5212
5213 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5214
5215 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5216 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5217 {
5218 Aura* aura = itr->second;
5220 continue;
5222 {
5223 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5224 {
5225 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5226
5227 // spell only removes 1 bleed effect do not continue
5228 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5229 {
5230 break;
5231 }
5232 }
5233 }
5234 }
5235
5236 for (; dispel_list.size(); dispel_list.pop())
5237 {
5238 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5239 }
5240
5241 // put in combat
5244}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:5447
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:468
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1198

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)
2696{
2698 return;
2699
2700 // Check for possible target
2701 if (!unitTarget || unitTarget->IsEngaged())
2702 return;
2703
2704 // target must be OK to do this
2706 return;
2707
2710
2713}
@ UNIT_STATE_CONFUSED
Definition: Unit.h:336
@ UNIT_STATE_FLEEING
Definition: Unit.h:332
@ UNIT_STATE_MOVING
Definition: Unit.h:364
@ UNIT_STATE_STUNNED
Definition: Unit.h:328
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
void SetFacingTo(float ori)
Definition: Unit.cpp:21475
bool IsEngaged() const
Definition: Unit.h:1721
void MoveDistract(uint32 time)
Definition: MotionMaster.cpp:706

References Unit::ClearUnitState(), damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Object::GetTypeId(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, TYPEID_UNIT, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_MOVING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2682{
2684 return;
2685
2687}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:1346

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4140{
4142 return;
4143
4145 return;
4146
4147 Player* caster = m_caster->ToPlayer();
4148 Player* target = unitTarget->ToPlayer();
4149
4150 // caster or target already have requested duel
4151 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4152 return;
4153
4154 // Players can only fight a duel in zones with this flag
4155 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4156 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4157 {
4158 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4159 return;
4160 }
4161
4162 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4163 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4164 {
4165 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4166 return;
4167 }
4168
4169 //CREATE DUEL FLAG OBJECT
4170 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4171 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4172
4173 Map* map = m_caster->GetMap();
4174 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4175 map, m_caster->GetPhaseMask(),
4179 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4180 {
4181 delete pGameObj;
4182 return;
4183 }
4184
4187 int32 duration = m_spellInfo->GetDuration();
4188 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4189 pGameObj->SetSpellId(m_spellInfo->Id);
4190
4191 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4192
4193 m_caster->AddGameObject(pGameObj);
4194 map->AddToMap(pGameObj, true);
4195 //END
4196
4197 // Send request
4198 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4199 data << pGameObj->GetGUID();
4200 data << caster->GetGUID();
4201 caster->GetSession()->SendPacket(&data);
4202 target->GetSession()->SendPacket(&data);
4203
4204 // create duel-info
4205 bool isMounted = (GetSpellInfo()->Id == 62875);
4206 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4207 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4208
4209 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4210 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4211
4212 sScriptMgr->OnPlayerDuelRequest(target, caster);
4213}
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition: UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition: UpdateFields.h:402
@ AREA_FLAG_ALLOW_DUELS
Definition: DBCEnums.h:245
@ SPELL_FAILED_NO_DUELING
Definition: SharedDefines.h:1000
@ SMSG_DUEL_REQUESTED
Definition: Opcodes.h:389
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition: GameObject.cpp:247
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1274
void SetSpellId(uint32 id)
Definition: GameObject.h:869
uint32 GetPhaseMask() const
Definition: Object.h:434
float GetOrientation() const
Definition: Position.h:120
PlayerSocial * GetSocial()
Definition: Player.h:1121
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193
Definition: Transport.h:112
uint32 GetFaction() const
Definition: Unit.h:1493
void AddGameObject(GameObject *gameObj)
Definition: Unit.cpp:6935
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:208
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5158
uint32 flags
Definition: DBCStructure.h:524

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::getLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetSocial(), GetSpellInfo(), Object::GetTypeId(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), WorldSession::SendPacket(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
672{
674 return;
675
677 return;
678
679 // selection by spell family
681 {
683 {
684 switch (m_spellInfo->Id)
685 {
686 // Trial of the Champion, Trample
687 case 67866:
688 {
690 unitTarget->CastSpell(unitTarget, 67867, false);
691 return;
692 }
693 // Trial of the Champion, Hammer of the Righteous
694 case 66867:
695 {
696 if( !unitTarget )
697 return;
698 if( unitTarget->HasAura(66940) )
699 m_caster->CastSpell(unitTarget, 66903, true);
700 else
701 m_caster->CastSpell(unitTarget, 66904, true);
702 return;
703 }
704 case 17731:
705 case 69294:
706 {
708 return;
709
713 trigger->CastSpell(trigger, 17731, false);
714
715 return;
716 }
717 // HoL, Arc Weld
718 case 59086:
719 {
721 m_caster->CastSpell(m_caster, 59097, true);
722
723 return;
724 }
725 }
726 break;
727 }
729 switch (m_spellInfo->Id)
730 {
731 case 31789: // Righteous Defense (step 1)
732 {
733 if (!unitTarget)
734 return;
735 // not empty (checked), copy
737
738 // remove invalid attackers
739 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
740 if (!(*aItr)->IsValidAttackTarget(m_caster))
741 aItr = attackers.erase(aItr);
742 else
743 ++aItr;
744
745 // selected from list 3
746 uint32 maxTargets = std::min<uint32>(3, attackers.size());
747 for (uint32 i = 0; i < maxTargets; ++i)
748 {
749 Unit::AttackerSet::iterator aItr = attackers.begin();
750 std::advance(aItr, urand(0, attackers.size() - 1));
751 m_caster->CastSpell((*aItr), 31790, true);
752 attackers.erase(aItr);
753 }
754
755 return;
756 }
757 }
758 break;
760 // Hunger for Blood
761 if( m_spellInfo->Id == 51662 )
762 {
763 m_caster->CastSpell(m_caster, 63848, true);
764 return;
765 }
766 break;
767 }
768
769 // pet auras
770 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
771 {
772 m_caster->AddPetAura(petSpell);
773 return;
774 }
775
776 // normal DB scripted effect
777 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
779
780 if (gameObjTarget)
781 {
782 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
783 }
784 else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT)
785 {
786 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
787 }
788 else if (itemTarget)
789 {
790 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
791 }
792}
@ TEMPSUMMON_TIMED_DESPAWN
Definition: Object.h:44
@ UNIT_FIELD_MOUNTDISPLAYID
Definition: UpdateFields.h:126
ScriptMapMap sSpellScripts
Definition: ObjectMgr.cpp:57
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3500
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3510
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3508
uint8 GetGoAnimProgress() const
Definition: GameObject.h:902
time_t GetRespawnTime() const
Definition: GameObject.h:876
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr) const
Definition: Object.cpp:2303
void AddPetAura(PetAura const *petSpell)
Definition: Unit.cpp:18203
std::unordered_set< Unit * > AttackerSet
Definition: Unit.h:1292
AttackerSet const & getAttackers() const
Definition: Unit.h:1383
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition: MapScripts.cpp:34
Definition: SpellMgr.h:463

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetTypeId(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Unit::isMoving(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5328{
5330 return;
5331
5332 if (!unitTarget)
5333 return;
5334
5335 Player* player = unitTarget->ToPlayer();
5336 if (!player)
5337 {
5338 return;
5339 }
5340
5341 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5342
5343 // -1 means all player equipped items and -2 all items
5344 if (slot < 0)
5345 {
5346 player->DurabilityPointsLossAll(damage, (slot < -1));
5348 return;
5349 }
5350
5351 // invalid slot value
5352 if (slot >= INVENTORY_SLOT_BAG_END)
5353 return;
5354
5355 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5356 {
5357 player->DurabilityPointsLoss(item, damage);
5358 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5359 }
5360}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:701
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:671
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:474
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4647
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4673
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5132

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5363{
5365 return;
5366
5367 if (!unitTarget)
5368 return;
5369
5370 Player* player = unitTarget->ToPlayer();
5371 if (!player)
5372 {
5373 return;
5374 }
5375
5376 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5377
5378 // FIXME: some spells effects have value -1/-2
5379 // Possibly its mean -1 all player equipped items and -2 all items
5380 if (slot < 0)
5381 {
5382 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5383 return;
5384 }
5385
5386 // invalid slot value
5387 if (slot >= INVENTORY_SLOT_BAG_END)
5388 return;
5389
5390 if (damage <= 0)
5391 return;
5392
5393 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5394 player->DurabilityLoss(item, float(damage) / 100.0f);
5395}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4603
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4629

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4450{
4452 return;
4453
4454 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4455 if (!unitTarget)
4456 return;
4457
4458 Player* item_owner = unitTarget->ToPlayer();
4459 if (!item_owner)
4460 {
4461 return;
4462 }
4463
4465 if (!item)
4466 return;
4467
4468 // must be equipped
4469 if (!item->IsEquipped())
4470 return;
4471
4472 if (m_spellInfo->Effects[effIndex].MiscValue)
4473 {
4474 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4475 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4476 if (!duration)
4477 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4478 if (!duration)
4479 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4480
4481 // Xinef: Venomhide poison, no other spell uses this effect...
4482 if (m_spellInfo->Id == 14792)
4483 duration = 5 * MINUTE * IN_MILLISECONDS;
4484
4485 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4486 if (!pEnchant)
4487 return;
4488
4489 // Always go to temp enchantment slot
4491
4492 // Enchantment will not be applied if a different one already exists
4493 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4494 return;
4495
4496 // Apply the temporary enchantment
4497 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4498 item_owner->ApplyEnchantment(item, slot, true);
4499 }
4500}
EnchantmentSlot
Definition: Item.h:162
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:164
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:691
bool IsEquipped() const
Definition: Item.cpp:791
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:922
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4337
uint32 charges
Definition: DBCStructure.h:1805

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2849{
2851 return;
2852
2854 return;
2855 if (!itemTarget)
2856 return;
2857
2858 Player* p_caster = m_caster->ToPlayer();
2859
2860 // Handle vellums
2862 {
2863 // destroy one vellum from stack
2864 uint32 count = 1;
2865 p_caster->DestroyItemCount(itemTarget, count, true);
2866 unitTarget = p_caster;
2867 // and add a scroll
2868 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2869 itemTarget = nullptr;
2870 m_targets.SetItemTarget(nullptr);
2871 }
2872 else
2873 {
2874 // do not increase skill if vellum used
2876 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2877
2878 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2879 if (!enchant_id)
2880 return;
2881
2882 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2883 if (!pEnchant)
2884 return;
2885
2886 // item can be in trade slot and have owner diff. from caster
2887 Player* item_owner = itemTarget->GetOwner();
2888 if (!item_owner)
2889 return;
2890
2891 // remove old enchanting before applying new if equipped
2893
2895
2896 // add new enchanting if equipped
2898
2899 item_owner->RemoveTradeableItem(itemTarget);
2901 }
2902}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:163
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1266
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4172
void SetItemTarget(Item *item)
Definition: Spell.cpp:374

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, ItemTemplate::Flags, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), Object::GetTypeId(), SpellInfo::Id, Item::IsArmorVellum(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), TYPEID_PLAYER, unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2905{
2907 return;
2908
2910 return;
2911 if (!itemTarget)
2912 return;
2913
2914 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2915 if (!enchant_id)
2916 return;
2917
2918 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2919 if (!pEnchant)
2920 return;
2921
2922 // support only enchantings with add socket in this slot
2923 {
2924 bool add_socket = false;
2925 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2926 {
2927 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2928 {
2929 add_socket = true;
2930 break;
2931 }
2932 }
2933 if (!add_socket)
2934 {
2935 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2937 return;
2938 }
2939 }
2940
2941 // item can be in trade slot and have owner diff. from caster
2942 Player* item_owner = itemTarget->GetOwner();
2943 if (!item_owner)
2944 return;
2945
2946 // remove old enchanting before applying new if equipped
2948
2950
2951 // add new enchanting if equipped
2953
2954 item_owner->RemoveTradeableItem(itemTarget);
2956}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Object::GetTypeId(), SpellInfo::Id, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, SpellItemEnchantmentEntry::type, and TYPEID_PLAYER.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2959{
2961 return;
2962
2964 return;
2965
2966 Player* p_caster = m_caster->ToPlayer();
2967
2968 // Rockbiter Weapon apply to both weapon
2969 if (!itemTarget)
2970 return;
2972 {
2973 uint32 spell_id = 0;
2974
2975 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2976 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2977 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2978 switch (damage)
2979 {
2980 // Rank 1
2981 case 2:
2982 spell_id = 36744;
2983 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2984 // Rank 2
2985 case 4:
2986 spell_id = 36753;
2987 break; // 0% [ 7% == 4, 14% == 4]
2988 case 5:
2989 spell_id = 36751;
2990 break; // 20%
2991 // Rank 3
2992 case 6:
2993 spell_id = 36754;
2994 break; // 0% [ 7% == 6, 14% == 6]
2995 case 7:
2996 spell_id = 36755;
2997 break; // 20%
2998 // Rank 4
2999 case 9:
3000 spell_id = 36761;
3001 break; // 0% [ 7% == 6]
3002 case 10:
3003 spell_id = 36758;
3004 break; // 14%
3005 case 11:
3006 spell_id = 36760;
3007 break; // 20%
3008 default:
3009 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
3010 return;
3011 }
3012
3013 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
3014 if (!spellInfo)
3015 {
3016 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
3017 return;
3018 }
3019
3020 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
3021 {
3022 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
3023 {
3024 if (item->IsFitToSpellRequirements(m_spellInfo))
3025 {
3026 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
3027 SpellCastTargets targets;
3028 targets.SetItemTarget(item);
3029 spell->prepare(&targets);
3030 }
3031 }
3032 }
3033 return;
3034 }
3035 if (!itemTarget)
3036 return;
3037
3038 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3039
3040 if (!enchant_id)
3041 {
3042 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3043 return;
3044 }
3045
3046 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3047 if (!pEnchant)
3048 {
3049 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3050 return;
3051 }
3052
3053 // select enchantment duration
3054 uint32 duration;
3055
3056 // rogue family enchantments exception by duration
3057 if (m_spellInfo->Id == 38615)
3058 duration = 1800; // 30 mins
3059 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3061 duration = 3600; // 1 hour
3062 // shaman family enchantments
3064 duration = 1800; // 30 mins
3065 // other cases with this SpellVisual already selected
3066 else if (m_spellInfo->SpellVisual[0] == 215)
3067 duration = 1800; // 30 mins
3068 // some fishing pole bonuses except Glow Worm which lasts full hour
3069 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3070 duration = 600; // 10 mins
3071 // shaman rockbiter enchantments
3072 else if (m_spellInfo->SpellVisual[0] == 0)
3073 duration = 1800; // 30 mins
3074 else if (m_spellInfo->Id == 29702)
3075 duration = 300; // 5 mins
3076 else if (m_spellInfo->Id == 37360)
3077 duration = 300; // 5 mins
3078 // default case
3079 else
3080 duration = 3600; // 1 hour
3081
3082 // item can be in trade slot and have owner diff. from caster
3083 Player* item_owner = itemTarget->GetOwner();
3084 if (!item_owner)
3085 return;
3086
3087 // remove old enchanting before applying new if equipped
3089
3090 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3091
3092 // add new enchanting if equipped
3094
3095 item_owner->RemoveTradeableItem(itemTarget);
3097}
WeaponAttackType
Definition: Unit.h:395
@ SPELLFAMILY_SHAMAN
Definition: SharedDefines.h:3511
Definition: Spell.h:109
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3490
std::array< uint32, 2 > SpellVisual
Definition: SpellInfo.h:377

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Object::GetTypeId(), Player::GetWeaponForAttack(), SpellInfo::Id, itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TYPEID_PLAYER.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1889{
1891 return;
1892
1893 if (!unitTarget)
1894 return;
1895 if (!unitTarget->IsAlive())
1896 return;
1897
1898 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1899 return;
1900
1901 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1902
1905 return;
1906
1907 if (unitTarget->GetMaxPower(power) == 0)
1908 return;
1909
1910 // Some level depends spells
1911 int level_multiplier = 0;
1912 int level_diff = 0;
1913 switch (m_spellInfo->Id)
1914 {
1915 case 9512: // Restore Energy
1916 level_diff = m_caster->getLevel() - 40;
1917 level_multiplier = 2;
1918 break;
1919 case 24571: // Blood Fury
1920 level_diff = m_caster->getLevel() - 60;
1921 level_multiplier = 10;
1922 break;
1923 case 24532: // Burst of Energy
1924 level_diff = m_caster->getLevel() - 60;
1925 level_multiplier = 4;
1926 break;
1927 case 31930: // Judgements of the Wise
1928 case 63375: // Improved Stormstrike
1929 case 68082: // Glyph of Seal of Command
1931 break;
1932 case 48542: // Revitalize
1934 break;
1935 case 67490: // Runic Mana Injector (mana gain increased by 25% for engineers - 3.2.0 patch change)
1936 {
1937 if (Player* player = m_caster->ToPlayer())
1938 if (player->HasSkill(SKILL_ENGINEERING))
1939 AddPct(damage, 25);
1940 break;
1941 }
1942 case 71132: // Glyph of Shadow Word: Pain
1943 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1944 break;
1945 default:
1946 break;
1947 }
1948
1949 if (level_diff > 0)
1950 damage -= level_multiplier * level_diff;
1951
1952 if (damage < 0)
1953 return;
1954
1956
1957 // Mad Alchemist's Potion
1958 if (m_spellInfo->Id == 45051)
1959 {
1960 // find elixirs on target
1961 bool guardianFound = false;
1962 bool battleFound = false;
1964 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1965 {
1966 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1967 if (!guardianFound)
1969 guardianFound = true;
1970 if (!battleFound)
1972 battleFound = true;
1973 if (battleFound && guardianFound)
1974 break;
1975 }
1976
1977 // get all available elixirs by mask and spell level
1978 std::set<uint32> availableElixirs;
1979 if (!guardianFound)
1980 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1981 if (!battleFound)
1982 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1983 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1984 {
1985 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1986 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->getLevel())
1987 availableElixirs.erase(itr++);
1988 else
1989 ++itr;
1990 }
1991
1992 if (!availableElixirs.empty())
1993 {
1994 // cast random elixir on target
1996 }
1997 }
1998}
SpellGroupSpecialFlags
Definition: SpellMgr.h:327
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition: SpellMgr.h:329
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition: SpellMgr.h:330
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition: SharedDefines.h:629
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3513
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2895
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:135
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition: Unit.cpp:12071

References AddPct(), CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::getLevel(), Unit::GetMaxPower(), Unit::getPowerType(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), SKILL_ENGINEERING, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
2001{
2003 return;
2004
2005 if (!unitTarget)
2006 return;
2007 if (!unitTarget->IsAlive())
2008 return;
2009
2010 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2011 return;
2012
2013 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2014
2016 return;
2017
2018 uint32 maxPower = unitTarget->GetMaxPower(power);
2019 if (maxPower == 0)
2020 return;
2021
2022 uint32 gain = CalculatePct(maxPower, damage);
2024}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Unit::getPowerType(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, TYPEID_PLAYER, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
304{
306 return;
307
308 if (!unitTarget || !unitTarget->IsAlive())
309 return;
310
311 if (unitTarget->IsPlayer())
313 else
314 {
316
317 uint32 absorb = dmgInfo.GetAbsorb();
318 uint32 resist = dmgInfo.GetResist();
319 uint32 envDamage = dmgInfo.GetDamage();
320
321 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
322 damage = envDamage;
323
325 }
326}
@ DAMAGE_FIRE
Definition: Player.h:832
bool IsPlayer() const
Definition: Object.h:194
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition: Player.cpp:756

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4548{
4550 return;
4551
4552 Player* player = m_caster->ToPlayer();
4553 if (!player)
4554 return;
4555
4556 Item* foodItem = itemTarget;
4557 if (!foodItem)
4558 return;
4559
4560 Pet* pet = player->GetPet();
4561 if (!pet)
4562 return;
4563
4564 if (!pet->IsAlive())
4565 return;
4566
4567 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4568 if (benefit <= 0)
4569 return;
4570
4571 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4572
4573 uint32 count = 1;
4574 player->DestroyItemCount(foodItem, count, true);
4576
4577 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4578}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5152

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
1023{
1025 return;
1026
1027 if (!unitTarget)
1028 return;
1029
1030 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1031
1032 // normal case
1033 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1034
1035 if (!spellInfo)
1036 {
1037 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1038 return;
1039 }
1040
1041 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1042 {
1043 switch (m_spellInfo->Id)
1044 {
1045 case 52588: // Skeletal Gryphon Escape
1046 case 48598: // Ride Flamebringer Cue
1048 break;
1049 case 52463: // Hide In Mine Car
1050 case 52349: // Overtake
1051 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1052 return;
1053 case 72378: // Blood Nova
1054 case 73058: // Blood Nova
1055 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1056 break;
1057 }
1058 }
1059
1060 CustomSpellValues values;
1061 // set basepoints for trigger with value effect
1063 {
1064 // maybe need to set value only when basepoints == 0?
1068 }
1069
1070 SpellCastTargets targets;
1071 targets.SetUnitTarget(m_caster);
1072
1073 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1074}
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:115
@ SPELLVALUE_BASE_POINT2
Definition: SpellDefines.h:116
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:114
@ SPELL_EFFECT_FORCE_CAST
Definition: SharedDefines.h:890
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition: SharedDefines.h:891
Definition: SpellDefines.h:162
void AddSpellMod(SpellValueMod mod, int32 value)
Definition: SpellDefines.h:164

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4804{
4806 return;
4807
4808 // xinef: clear focus
4810
4812 data << m_caster->GetGUID();
4813
4815 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4816 Cell::VisitWorldObjects(m_caster, notifier, dist);
4817
4818 // xinef: we should also force pets to remove us from current target
4819 Unit::AttackerSet attackerSet;
4820 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4821 if ((*itr)->GetTypeId() == TYPEID_UNIT && !(*itr)->CanHaveThreatList())
4822 attackerSet.insert(*itr);
4823
4824 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4825 (*itr)->AttackStop();
4826
4827 // Xinef: Mirror images code Initialize Images
4828 if (m_spellInfo->Id == 58836)
4829 {
4830 std::vector<Unit*> images;
4831 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4832 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4833 images.push_back(*itr);
4834
4835 if (images.empty())
4836 return;
4837
4838 UnitList targets;
4839 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4842 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4843 {
4844 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4845 continue;
4846
4847 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4848 {
4849 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4850 {
4851 SpellInfo const* si = spell->GetSpellInfo();
4852 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->GetTypeId() == TYPEID_UNIT)
4853 {
4854 Creature* c = (*iter)->ToCreature();
4855 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4856 continue;
4857 }
4858
4859 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4860 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4861 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4862 {
4863 // at least one effect truly targets an unit, interrupt the spell
4864 interrupt = true;
4865 break;
4866 }
4867
4868 if (interrupt)
4869 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4870 }
4871 }
4872 }
4873 }
4874}
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
std::list< Unit * > UnitList
Definition: Unit.h:240
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:102
@ CREATURE_ELITE_WORLDBOSS
Definition: SharedDefines.h:2706
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:589
@ SMSG_CLEAR_TARGET
Definition: Opcodes.h:989
bool IsDungeonBoss() const
Definition: Creature.cpp:3168
uint32 rank
Definition: CreatureData.h:199
ControlSet m_Controlled
Definition: Unit.h:2083
void SendClearTarget()
Definition: Unit.cpp:21172
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:207
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:193
Definition: GridNotifiers.h:130
Definition: GridNotifiers.h:420
Definition: GridNotifiers.h:858

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), TYPEID_UNIT, UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, Cell::VisitAllObjects(), and Cell::VisitWorldObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5969{
5971 return;
5972
5973 if (!gameObjTarget)
5974 return;
5975
5976 Unit* caster = m_originalCaster;
5977 if (!caster)
5978 return;
5979
5980 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5982 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5983 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5985}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition: GameObject.cpp:2255
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:10851
Definition: DBCStructure.h:930
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:942

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5999{
6001 return;
6002
6004 return;
6005
6008}
GameObjectDestructibleState
Definition: SharedDefines.h:1598
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition: GameObject.cpp:2311

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1483{
1485 return;
1486
1487 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1488 {
1489 // Try to get original caster
1491
1492 // Skip if m_originalCaster not available
1493 if (!caster)
1494 return;
1495
1496 int32 addhealth = damage;
1497
1498 // Vessel of the Naaru (Vial of the Sunwell trinket)
1499 if (m_spellInfo->Id == 45064)
1500 {
1501 // Amount of heal - depends from stacked Holy Energy
1502 int damageAmount = 0;
1503 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1504 {
1505 damageAmount += aurEff->GetAmount();
1507 }
1508
1509 addhealth += damageAmount;
1510 }
1511 // Swiftmend - consumes Regrowth or Rejuvenation
1513 {
1515 // find most short by duration
1516 AuraEffect* forcedTargetAura = nullptr;
1517 AuraEffect* targetAura = nullptr;
1518 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1519 {
1520 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1521 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1522 {
1523 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1524 {
1525 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1526 forcedTargetAura = *i;
1527 }
1528 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1529 targetAura = *i;
1530 }
1531 }
1532
1533 if (forcedTargetAura)
1534 targetAura = forcedTargetAura;
1535
1536 if (!targetAura)
1537 {
1538 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1539 return;
1540 }
1541
1542 int32 tickheal = targetAura->GetAmount();
1543 if (Unit* auraCaster = targetAura->GetCaster())
1544 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1545
1546 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1547 //It is said that talent bonus should not be included
1548
1549 int32 tickcount = 0;
1550 // Rejuvenation
1551 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1552 tickcount = 4;
1553 // Regrowth
1554 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1555 tickcount = 6;
1556
1557 addhealth += tickheal * tickcount;
1558
1559 // Glyph of Swiftmend
1560 if (!caster->HasAura(54824))
1561 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1562
1563 //addhealth += tickheal * tickcount;
1564 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1565 }
1566 // Death Pact - return pct of max health to caster
1568 {
1569 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1570 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1571 }
1572 else if (m_spellInfo->Id != 33778) // not lifebloom
1573 {
1574 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1575 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1576 }
1577
1578 // Implemented this way as there is no other way to do it currently (that I know :P)...
1579 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1580 {
1582 {
1583 m_damage = 0;
1584 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1585 return;
1586 }
1587 }
1588
1589 m_damage -= addhealth;
1590 }
1591}
@ DOT
Definition: Unit.h:437
@ SPELL_AURA_PERIODIC_HEAL
Definition: SpellAuraDefines.h:71
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3507
@ AURA_STATE_SWIFTMEND
Definition: SharedDefines.h:1279
@ SPELL_SCHOOL_MASK_HOLY
Definition: SharedDefines.h:270
uint32 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:1447
SpellInfo const * GetSpellInfo() const
Definition: SpellAuraEffects.h:54
uint32 GetId() const
Definition: SpellAuraEffects.cpp:434
Unit * GetCaster() const
Definition: SpellAuraEffects.h:47
Aura * GetBase() const
Definition: SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition: SpellAuraEffects.h:48
int32 GetAmount() const
Definition: SpellAuraEffects.h:63
uint32 TargetAuraState
Definition: SpellInfo.h:338

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3696{
3698 return;
3699
3700 if (!unitTarget || !unitTarget->IsAlive())
3701 return;
3702
3703 int32 addhealth = 0;
3704
3705 // damage == 0 - heal for caster max health
3706 if (damage == 0)
3707 addhealth = m_caster->GetMaxHealth();
3708 else
3709 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3710
3711 m_healing += addhealth;
3712}
uint32 GetMaxHealth() const
Definition: Unit.h:1439

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), Unit::IsAlive(), m_caster, m_healing, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1629{
1631 return;
1632
1633 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1634 return;
1635
1638
1639 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1640
1641 // xinef: handled in spell.cpp
1642 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1643
1644 m_damage += damage;
1645 // get max possible damage, don't count overkill for heal
1646 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1647
1648 //if (m_caster->IsAlive())
1649 //{
1650 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1651 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1652
1653 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1654 //}
1655}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:12558
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:12415

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4520{
4522 return;
4523
4524 if (!unitTarget)
4525 return;
4526
4527 Player* player = unitTarget->ToPlayer();
4528 if (!player)
4529 {
4530 return;
4531 }
4532
4533 uint8 currentDrunk = player->GetDrunkValue();
4534 uint8 drunkMod = damage;
4535 if (currentDrunk + drunkMod > 100)
4536 {
4537 currentDrunk = 100;
4538 if (rand_chance() < 25.0f)
4539 player->CastSpell(player, 67468, false); // Drunken Vomit
4540 }
4541 else
4542 currentDrunk += drunkMod;
4543
4544 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4545}
double rand_chance()
Definition: Random.cpp:83
uint8 GetDrunkValue() const
Definition: Player.h:2121
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:973

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, rand_chance(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
280{
282 return;
283
284 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
285 return;
286
289 return;
290
291 if (m_caster == unitTarget) // prevent interrupt message
292 finish();
293
294 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
295 data << m_caster->GetGUID();
296 data << unitTarget->GetGUID();
297 data << uint32(m_spellInfo->Id);
298 m_caster->SendMessageToSet(&data, true);
299
301}
@ CHEAT_GOD
Definition: Player.h:991
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:269
@ SMSG_SPELLINSTAKILLLOG
Definition: Opcodes.h:845
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition: Unit.cpp:1056

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Object::GetTypeId(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3715{
3717 return;
3718
3719 if (!unitTarget || !unitTarget->IsAlive())
3720 return;
3721
3723 // also exist case: apply cooldown to interrupted cast only and to all spells
3724 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3726 {
3728 {
3729 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3730 // check if we can interrupt spell
3731 if ((spell->getState() == SPELL_STATE_CASTING
3732 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3736 {
3737 if (m_originalCaster)
3738 {
3740 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3741 }
3742 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3744 }
3745 }
3746 }
3747}
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:984
CurrentSpellTypes
Definition: Unit.h:977
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:980
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:981
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:38
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:30
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4568
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:15569
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:2292
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5125
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:352
uint32 InterruptFlags
Definition: SpellInfo.h:350

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1096{
1098 return;
1099
1100 if (m_caster->IsInFlight())
1101 return;
1102
1103 if (!unitTarget)
1104 return;
1105
1106 float speedXY, speedZ;
1107 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1108 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1109
1111 {
1112 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1113 }
1114}
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition: MotionMaster.h:225
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition: SpellEffects.cpp:1179

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Object::GetTypeId(), Unit::IsInFlight(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1117{
1119 return;
1120
1121 if (m_caster->IsInFlight())
1122 return;
1123
1124 if (!m_targets.HasDst() || m_caster->GetVehicle())
1125 return;
1126
1127 // Init dest coordinates
1128 float x, y, z;
1129 destTarget->GetPosition(x, y, z);
1130 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1131 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1132 return;
1133
1134 float speedXY, speedZ;
1135 float dist = m_caster->GetExactDist2d(x, y);
1136 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1137
1138 // Override, calculations are incorrect
1139 if (m_spellInfo->Id == 49376) // feral charge
1140 {
1141 speedXY = pow(speedZ * 10, 8);
1143
1144 if (Player* player = m_caster->ToPlayer())
1145 {
1146 player->SetCanTeleport(true);
1147 }
1148
1150 {
1151 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1152 }
1153
1154 return;
1155 }
1156
1157 if (m_spellInfo->Id == 57604) // death grip
1158 {
1159 speedZ = 3.0f;
1160 speedXY = 50.0f;
1161 }
1162
1163 // crash fix?
1164 if (speedXY < 1.0f)
1165 speedXY = 1.0f;
1166
1167 if (Player* player = m_caster->ToPlayer())
1168 {
1169 player->SetCanTeleport(true);
1170 }
1171 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1172
1174 {
1175 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1176 }
1177}
@ UNIT_FIELD_TARGET
Definition: UpdateFields.h:92
#define INVALID_HEIGHT
Definition: Map.h:164
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:339

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5758{
5760 return;
5761
5762 if (!unitTarget)
5763 return;
5764
5766 if (!player)
5767 {
5768 return;
5769 }
5770
5771 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5772 if (!creatureEntry)
5773 {
5774 if (m_spellInfo->Id == 42793) // Burn Body
5775 creatureEntry = 24008; // Fallen Combatant
5776 }
5777
5778 if (creatureEntry)
5779 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5780}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12445

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5741{
5743 return;
5744
5745 if (!unitTarget)
5746 return;
5747
5749 if (!player)
5750 {
5751 return;
5752 }
5753
5754 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5755}
void KilledMonsterCredit(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition: PlayerQuest.cpp:1904

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Player::KilledMonsterCredit(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
5025{
5027 return;
5028
5029 if (!unitTarget)
5030 return;
5031
5032 // Xinef: allow entry specific spells to skip those checks
5033 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
5034 {
5036 return;
5037
5038 if (unitTarget->GetVehicle())
5039 return;
5040
5041 if (Creature* creatureTarget = unitTarget->ToCreature())
5042 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
5043 return;
5044 }
5045
5046 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
5048 return;
5049
5050 // Instantly interrupt non melee spells being casted
5053
5054 float ratio = 0.1f;
5055 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
5056 float speedz = float(damage) * ratio;
5057 if (speedxy <= 0.1f && speedz <= 0.1f)
5058 return;
5059
5060 float x, y;
5061 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
5062 {
5063 if (m_targets.HasDst())
5064 destTarget->GetPosition(x, y);
5065 else
5066 return;
5067 }
5068 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5069 {
5070 m_caster->GetPosition(x, y);
5071 }
5072
5073 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5074
5076 {
5077 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5078 }
5079}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition: SharedDefines.h:894
@ CREATURE_TYPE_GIANT
Definition: SharedDefines.h:2604
@ CREATURE_TYPE_BEAST
Definition: SharedDefines.h:2600
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4654
uint32 GetCreatureType() const
Definition: Unit.cpp:15895
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:20031

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Object::GetTypeId(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), Unit::IsNonMeleeSpellCast(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4734{
4736 return;
4737
4738 if (!unitTarget || unitTarget->IsInFlight())
4739 return;
4740
4741 if (!m_targets.HasDst())
4742 return;
4743
4744 Position dstpos = destTarget->GetPosition();
4746}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:20844

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5082{
5084 return;
5085
5086 if (!unitTarget)
5087 return;
5088
5089 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5090 float speedz = damage / 10.0f;
5091 //1891: Disengage
5093
5095 {
5096 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5097 }
5098
5099 // xinef: changes fall time
5102}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3509
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:20392

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::GetTypeId(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3270{
3272 return;
3273
3274 if (!unitTarget)
3275 return;
3276
3277 if (unitTarget->ToPlayer())
3278 {
3279 EffectLearnSpell(effIndex);
3280 return;
3281 }
3282 Pet* pet = unitTarget->ToPet();
3283 if (!pet)
3284 return;
3285
3286 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3287 if (!learn_spellproto)
3288 return;
3289
3290 pet->learnSpell(learn_spellproto->Id);
3292 pet->GetOwner()->PetSpellInitialize();
3293}
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1876
void EffectLearnSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:2547

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2787{
2789 return;
2790
2792 return;
2793
2794 if (damage < 0)
2795 return;
2796
2797 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2798 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2799 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2800}
uint16 GetPureSkillValue(uint32 skill) const
Definition: Player.cpp:5405
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5217

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::GetTypeId(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2548{
2550 return;
2551
2552 if (!unitTarget)
2553 return;
2554
2556 {
2557 if (unitTarget->ToPet())
2558 EffectLearnPetSpell(effIndex);
2559 return;
2560 }
2561
2562 Player* player = unitTarget->ToPlayer();
2563
2564 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2565 player->learnSpell(spellToLearn);
2566
2567 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2568 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2569}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3224
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:3269

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), Object::GetTypeId(), SpellInfo::Id, Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), TYPEID_PLAYER, and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5568{
5570 return;
5571
5573 return;
5574
5575 Player* p_caster = m_caster->ToPlayer();
5577 return;
5578
5579 if (itemTarget->GetCount() < 5)
5580 return;
5581
5582 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5583 {
5584 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5585 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5586 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5587 }
5588
5590}
@ LOOT_MILLING
Definition: LootMgr.h:88
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:108
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7639
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:724

References CONFIG_SKILL_MILLING, effectHandleMode, ItemTemplate::Flags, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), Object::GetTypeId(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), TYPEID_PLAYER, and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5398{
5400 return;
5401
5402 if (!unitTarget)
5403 return;
5404
5406}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:493
ThreatMgr & GetThreatMgr()
Definition: Unit.h:2404

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
244{
245 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
246}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2093{
2095 return;
2096
2098 {
2099 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2100 return;
2101 }
2102
2103 Player* player = m_caster->ToPlayer();
2104
2105 uint32 lockId = 0;
2106 ObjectGuid guid;
2107
2108 // Get lockId
2109 if (gameObjTarget)
2110 {
2111 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2112 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2113 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2114 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2115 {
2116 //CanUseBattlegroundObject() already called in CheckCast()
2117 // in battleground check
2118 if (Battleground* bg = player->GetBattleground())
2119 {
2120 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2121 return;
2122 }
2123 }
2124 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2125 {
2126 //CanUseBattlegroundObject() already called in CheckCast()
2127 // in battleground check
2128 if (Battleground* bg = player->GetBattleground())
2129 {
2130 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2131 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2132 return;
2133 }
2134 }
2135 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2136 {
2139 {
2141 }
2142 return;
2143 }
2145 // handle outdoor pvp object opening, return true if go was registered for handling
2146 // these objects must have been spawned by outdoorpvp!
2147 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2148 return;
2149 lockId = goInfo->GetLockId();
2150 guid = gameObjTarget->GetGUID();
2151 }
2152 else if (itemTarget)
2153 {
2154 lockId = itemTarget->GetTemplate()->LockID;
2155 guid = itemTarget->GetGUID();
2156 }
2157 else
2158 {
2159 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2160 return;
2161 }
2162
2163 SkillType skillId = SKILL_NONE;
2164 int32 reqSkillValue = 0;
2165 int32 skillValue;
2166
2167 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2168 if (res != SPELL_CAST_OK)
2169 {
2170 SendCastResult(res);
2171 return;
2172 }
2173
2174 if (gameObjTarget)
2175 SendLoot(guid, LOOT_SKINNING);
2176 else if (itemTarget)
2177 {
2179 if (Player* itemOwner = itemTarget->GetOwner())
2180 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2181 }
2182
2183 // not allow use skill grow at item base open
2184 if (!m_CastItem && skillId != SKILL_NONE)
2185 {
2186 // update skill if really known
2187 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2188 {
2189 if (gameObjTarget)
2190 {
2191 // Allow one skill-up until respawned
2192 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2193 {
2195 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2196 }
2197
2198 }
2199 else if (itemTarget)
2200 {
2201 // Do one skill-up
2202 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2203 }
2204 }
2205 }
2207}
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:803
@ ITEM_CHANGED
Definition: Item.h:204
@ ITEM_FIELD_FLAG_UNLOCKED
Definition: ItemTemplate.h:112
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ LOOT_SKINNING
Definition: LootMgr.h:86
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:106
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1533
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1556
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1542
@ BATTLEGROUND_EY
Definition: SharedDefines.h:3459
Definition: GameObject.h:41
uint32 GetAutoCloseTime() const
Definition: GameObject.h:520
struct GameObjectTemplate::@209::@212 button
uint32 noDamageImmune
Definition: GameObject.h:58
uint32 losOK
Definition: GameObject.h:74
uint32 GetLockId() const
Definition: GameObject.h:437
struct GameObjectTemplate::@209::@220 goober
Unit * GetOwner() const
Definition: GameObject.cpp:1209
void AddToSkillupList(ObjectGuid playerGuid)
Definition: GameObject.cpp:3087
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition: GameObject.cpp:3093
LootState getLootState() const
Definition: GameObject.h:917
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2413
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:716
Definition: Object.h:97
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition: Spell.cpp:5140
void SendLoot(ObjectGuid guid, LootType loottype)
Definition: SpellEffects.cpp:2026

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), Object::GetTypeId(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, TYPEID_PLAYER, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4716{
4718 return;
4719
4721 m_caster->ToPlayer()->SetCanParry(true);
4722}
void SetCanParry(bool value)
Definition: Player.cpp:12836

References effectHandleMode, Object::GetTypeId(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1855{
1857 return;
1858
1859 if (!m_spellAura)
1860 {
1862 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1863
1864 // Caster not in world, might be spell triggered from aura removal
1865 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1866 return;
1867 DynamicObject* dynObj = new DynamicObject(false);
1868 if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
1869 {
1870 delete dynObj;
1871 return;
1872 }
1873
1875 {
1876 m_spellAura = aura;
1879 }
1880 else
1881 return;
1882 }
1883
1886}
@ DYNAMIC_OBJECT_AREA_SPELL
Definition: DynamicObject.h:30
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1597
DynamicObject * GetDynobjOwner() const
Definition: SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition: SpellAuras.cpp:354

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)
2716{
2718 return;
2719
2721 return;
2722
2723 // victim must be creature and attackable
2725 return;
2726
2727 // victim have to be alive and humanoid or undead
2730}
@ LOOT_PICKPOCKETING
Definition: LootMgr.h:82
uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD
Definition: SharedDefines.h:2616
uint32 GetCreatureTypeMask() const
Definition: Unit.h:1526

References CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD, effectHandleMode, Unit::GetCreatureTypeMask(), Object::GetGUID(), Object::GetTypeId(), Unit::IsAlive(), Unit::IsFriendlyTo(), LOOT_PICKPOCKETING, m_caster, Player::SendLoot(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, and unitTarget.

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6174{
6176 return;
6177
6178 if (!unitTarget)
6179 return;
6180
6181 Player* player = unitTarget->ToPlayer();
6182 if (!player)
6183 {
6184 return;
6185 }
6186
6187 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6188
6189 if (!sSoundEntriesStore.LookupEntry(soundid))
6190 {
6191 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6192 return;
6193 }
6194
6196}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition: MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6233{
6235 return;
6236
6237 if (!unitTarget)
6238 return;
6239
6240 Player* player = unitTarget->ToPlayer();
6241 if (!player)
6242 {
6243 return;
6244 }
6245
6246 switch (m_spellInfo->Id)
6247 {
6248 case 58730: // Restricted Flight Area
6249 case 58600: // Restricted Flight Area
6251 break;
6252 default:
6253 break;
6254 }
6255
6256 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6257
6258 if (!sSoundEntriesStore.LookupEntry(soundId))
6259 {
6260 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6261 return;
6262 }
6263
6264 player->PlayDirectSound(soundId, player);
6265}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:727
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2838
void SendNotification(const char *format,...) ATTR_PRINTF(2
Definition: WorldSession.cpp:763

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), WorldSession::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1441{
1443 return;
1444
1445 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1446 return;
1447
1448 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1449
1451 return;
1452
1453 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1454 if (m_spellInfo->Id == 8129)
1455 {
1458 damage = std::min(damage, maxDamage);
1459
1460 // Remove fear
1462 }
1463
1464 int32 power = damage;
1465 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1466 if (PowerType == POWER_MANA)
1467 power -= unitTarget->GetSpellCritDamageReduction(power);
1468
1469 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1470
1471 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1472 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1473
1474 // add log data before multiplication (need power amount, not damage)
1475 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1476
1477 newDamage = int32(newDamage * dmgMultiplier);
1478
1479 m_damage += newDamage;
1480}
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:14895
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition: Unit.h:1622
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition: Spell.cpp:5109

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::getPowerType(), Unit::GetSpellCritDamageReduction(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1362{
1364 return;
1365
1366 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1367 return;
1368
1369 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1370
1372 return;
1373
1374 // add spell damage bonus
1377
1378 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1379 int32 power = damage;
1380 if (PowerType == POWER_MANA)
1381 power -= unitTarget->GetSpellCritDamageReduction(power);
1382
1383 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1384
1385 float gainMultiplier = 0.0f;
1386
1387 // Don`t restore from self drain
1388 if (m_caster != unitTarget)
1389 {
1390 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1391
1392 int32 gain = int32(newDamage * gainMultiplier);
1393
1395 }
1396 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1397}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::getPowerType(), Unit::GetSpellCritDamageReduction(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2319{
2321 return;
2322
2324 return;
2325 Player* p_target = m_caster->ToPlayer();
2326
2328 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2329 {
2330 p_target->AddWeaponProficiency(subClassMask);
2332 }
2333 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2334 {
2335 p_target->AddArmorProficiency(subClassMask);
2337 }
2338}
uint32 GetArmorProficiency() const
Definition: Player.h:1329
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:9833
uint32 GetWeaponProficiency() const
Definition: Player.h:1328
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1327
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1326
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:374

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Object::GetTypeId(), Player::GetWeaponProficiency(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2690{
2692 EffectNULL(effIndex);
2693}
void EffectNULL(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:243

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5170{
5172 return;
5173
5174 if (!unitTarget)
5175 return;
5176
5177 Position pos;
5178 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5179 {
5180 if (m_targets.HasDst())
5181 pos.Relocate(*destTarget);
5182 else
5183 return;
5184 }
5185 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5186 {
5187 // Xinef: Increase Z position a little bit, should protect from falling through textures
5189 }
5190
5191 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f;
5192 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5193
5194 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5195
5197 {
5198 sScriptMgr->AnticheatSetSkipOnePacketForASH(unitTarget->ToPlayer(), true);
5199 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5200 }
5201}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition: SharedDefines.h:895
double gravity
Definition: MovementUtil.cpp:24
void Relocate(float x, float y)
Definition: Position.h:73

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Object::GetTypeId(), Movement::gravity, SpellCastTargets::HasDst(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5105{
5107 return;
5108
5109 if (!unitTarget)
5110 return;
5111
5112 Player* player = unitTarget->ToPlayer();
5113 if (!player)
5114 {
5115 return;
5116 }
5117
5118 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5119
5120 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5121
5122 if (!quest)
5123 return;
5124
5125 // Player has never done this quest
5126 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5127 return;
5128
5129 // remove all quest entries for 'entry' from quest log
5130 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5131 {
5132 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5133 if (logQuest == quest_id)
5134 {
5135 player->SetQuestSlot(slot, 0);
5136
5137 // we ignore unequippable quest items in this case, it's still be equipped
5138 player->TakeQuestSourceItem(logQuest, false);
5139
5140 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5141 {
5142 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5143 player->UpdatePvPState();
5144 }
5145 }
5146 }
5147
5148 player->RemoveRewardedQuest(quest_id);
5149 player->RemoveActiveQuest(quest_id, false);
5150}
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
bool IsHostile
Definition: Player.h:361
bool IsInHostileArea
Definition: Player.h:362
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2472
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1393
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1449
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1453
PvPInfo pvpInfo
Definition: Player.h:1796
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1353
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1472
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1407
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1490
Definition: QuestDef.h:207
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:218

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4775{
4777 return;
4778
4779 if (!unitTarget)
4780 return;
4781
4782 Player* player = unitTarget->ToPlayer();
4783 if (!player)
4784 {
4785 return;
4786 }
4787
4788 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4789 if (questId)
4790 {
4791 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4792 if (!quest)
4793 return;
4794
4795 uint16 logSlot = player->FindQuestSlot(questId);
4796 if (logSlot < MAX_QUEST_LOG_SIZE)
4797 player->AreaExploredOrEventHappens(questId);
4798 else if (player->CanTakeQuest(quest, false)) // never rewarded before
4799 player->CompleteQuest(questId); // quest not in log - for internal use
4800 }
4801}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1759
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:250
void CompleteQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:596
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1768

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), Player::CompleteQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5783{
5785 return;
5786
5787 if (!unitTarget)
5788 return;
5789
5790 Player* player = unitTarget->ToPlayer();
5791 if (!player)
5792 {
5793 return;
5794 }
5795
5796 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5797}
void FailQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:877

References effectHandleMode, SpellInfo::Effects, Player::FailQuest(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5800{
5802 return;
5803
5804 if (!unitTarget)
5805 return;
5806
5807 Player* player = unitTarget->ToPlayer();
5808 if (!player)
5809 return;
5810
5811 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5812 {
5813 if (!player->CanTakeQuest(quest, false))
5814 return;
5815
5816 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5817 player->AddQuestAndCheckCompletion(quest, player);
5818
5819 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5820 }
5821}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:385
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:263
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:419
PlayerMenu * PlayerTalkClass
Definition: Player.h:2187

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6322{
6324 return;
6325
6327 return;
6328
6329 Player* player = m_caster->ToPlayer();
6330
6331 if (!player)
6332 return;
6333
6334 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6335
6336 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6337 if (!pProto)
6338 {
6339 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6340 return;
6341 }
6342
6343 if (Item* pItem = player->GetItemByEntry(item_id))
6344 {
6345 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6346 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6347 pItem->SetState(ITEM_CHANGED, player);
6348 }
6349}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::GetTypeId(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5960{
5962 return;
5963
5964 if (unitTarget)
5966}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:2612

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6268{
6270 return;
6271
6272 if (!unitTarget)
6273 return;
6274 // there may be need of specifying casterguid of removed auras
6275 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6276}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6162{
6164 return;
6165
6168 return;
6169
6171}
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
@ UNIT_CAN_BE_RENAMED
Definition: Unit.h:149
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:913
PetType getPetType() const
Definition: Pet.h:50

References effectHandleMode, Pet::getPetType(), Object::GetTypeId(), HUNTER_PET, Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), TYPEID_UNIT, UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4749{
4751 return;
4752
4753 if (!unitTarget)
4754 return;
4755
4756 Player* player = unitTarget->ToPlayer();
4757 if (!player)
4758 {
4759 return;
4760 }
4761
4762 float repChange = static_cast<float>(damage);
4763
4764 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4765
4766 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4767 if (!factionEntry)
4768 return;
4769
4770 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4771 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4772}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition: Player.h:246
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition: Player.cpp:5756
ReputationMgr & GetReputationMgr()
Definition: Player.h:2075
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition: ReputationMgr.h:118
Definition: DBCStructure.h:898

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4667{
4669 return;
4670
4671 if (!unitTarget)
4672 return;
4673
4674 if (!unitTarget)
4675 return;
4676
4677 Player* target = unitTarget->ToPlayer();
4678 if (!target)
4679 {
4680 return;
4681 }
4682
4683 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4684 return;
4685
4686 if (target->isResurrectRequested()) // already have one active request
4687 return;
4688
4689 uint32 health = target->CountPctFromMaxHealth(damage);
4691
4692 ExecuteLogEffectResurrect(effIndex, target);
4693
4695 SendResurrectRequest(target);
4696}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition: Player.h:1765
bool isResurrectRequested() const
Definition: Player.h:1777
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition: Spell.cpp:5170
void SendResurrectRequest(Player *target)
Definition: Spell.cpp:5232

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5247{
5249 return;
5250
5251 if (damage < 0)
5252 return;
5253
5254 Player* player = m_caster->ToPlayer();
5255 if (!player)
5256 {
5257 return;
5258 }
5259
5260 Pet* pet = player->GetPet();
5261 if (!pet)
5262 {
5263 // Position passed to SummonPet is irrelevant with current implementation,
5264 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5265 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5266 return;
5267 }
5268
5270 if (pet->IsAlive())
5271 {
5272 return;
5273 }
5274
5275 // Reposition the pet's corpse before reviving so as not to grab aggro
5276 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5277 float x, y, z; // Will be used later to reposition the pet if we have one
5278 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5279 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5280 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5283 pet->setDeathState(ALIVE);
5284 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5286 pet->SetDisplayId(pet->GetNativeDisplayId());
5287
5288 // xinef: restore movement
5289 if (auto ci = pet->GetCharmInfo())
5290 {
5291 ci->SetIsAtStay(false);
5292 ci->SetIsFollowing(false);
5293 }
5294
5296}
#define PET_FOLLOW_DIST
Definition: PetDefines.h:193
@ SUMMON_PET
Definition: PetDefines.h:31
@ ALIVE
Definition: Unit.h:316
@ UNIT_STATE_POSSESSED
Definition: Unit.h:341
@ UNIT_STATE_ALL_STATE
Definition: Unit.h:373
@ UNIT_DYNFLAG_NONE
Definition: SharedDefines.h:3092
float GetFollowAngle() const override
Definition: TemporarySummon.h:77
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition: Object.cpp:2647
void setDeathState(DeathState s, bool despawn=false) override
Set DeathState.
Definition: Pet.cpp:618
void SetDisplayId(uint32 modelId) override
Change creature DisplayID temporarly.
Definition: Pet.cpp:2366
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8789
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:1326
void SetHealth(uint32 val)
Definition: Unit.cpp:16191
uint32 GetNativeDisplayId() const
Definition: Unit.h:2427
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:1480

References ALIVE, Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4047{
4049 return;
4050
4051 if (!unitTarget)
4052 return;
4053
4055 {
4057 // Xinef: replaced with CombatStop(false)
4060
4061 // Night Elf: Shadowmeld only resets threat temporarily
4062 if (m_spellInfo->Id != 59646)
4064
4066 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4067 }
4068 else
4069 {
4070 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4071 unitTarget->CombatStop(true);
4072 }
4073
4074 UnitList targets;
4075 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4078 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4079 {
4080 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4081 continue;
4082
4084 {
4085 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4086 {
4087 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4088 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->GetTypeId() == TYPEID_UNIT)
4089 {
4090 Creature* c = (*iter)->ToCreature();
4091 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4092 continue;
4093 }
4094 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4095 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4096 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4097 {
4098 // at least one effect truly targets an unit, interrupt the spell
4099 interrupt = true;
4100 break;
4101 }
4102 if (interrupt)
4103 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4104 }
4105 }
4106 }
4107
4108 // Xinef: Set last sanctuary time
4110
4111 // Vanish allows to remove all threat and cast regular stealth so other spells can be used
4115 {
4117
4118 //Clean Escape
4119 if (m_caster->HasAura(23582))
4120 m_caster->CastSpell(m_caster, 23583, true);
4121 }
4122}
#define CURRENT_MAX_SPELL
Definition: Unit.h:985
@ SPELL_AURA_MOD_ROOT
Definition: SpellAuraDefines.h:89
@ SPELLFAMILYFLAG_ROGUE_VANISH
Definition: SpellMgr.h:54
void UpdateVisibility(bool checkThreat)
Definition: HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition: HostileRefMgr.cpp:85
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:11245
void RemoveAllAttackers()
Definition: Unit.cpp:11288
bool AttackStop()
Definition: Unit.cpp:11212
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:120

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CastSpell(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), Object::GetTypeId(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Unit::RemoveAurasByType(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_AURA_MOD_ROOT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILYFLAG_ROGUE_VANISH, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitAllObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
329{
331 return;
332
333 if (unitTarget && unitTarget->IsAlive())
334 {
335 bool apply_direct_bonus = true;
337 {
339 {
340 // Meteor like spells (divided damage to targets)
342 {
343 uint32 count = 0;
344 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
345 if (ihit->effectMask & (1 << effIndex))
346 ++count;
347
348 damage /= count; // divide to all targets
349 }
350 break;
351 }
353 {
354 // Shield Slam
355 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
356 {
357 uint8 level = m_caster->getLevel();
358 // xinef: shield block should increase the limit
359 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
360 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
361
362 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
363 }
364 // Victory Rush
365 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
367 // Shockwave
368 else if (m_spellInfo->Id == 46968)
369 {
371 if (pct > 0)
373 break;
374 }
375 break;
376 }
378 {
379 // Incinerate Rank 1 & 2
380 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
381 {
382 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
383 // Check aura state for speed but aura state set not only for Immolate spell
385 {
387 damage += damage / 4;
388 }
389 }
390 // Immolate - hidden delay for conflagrate
391 else if (m_spellInfo->SpellFamilyFlags[0] & 0x4)
392 {
393 }
394 // Conflagrate - consumes Immolate or Shadowflame
396 {
397 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
398
400 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
401 {
402 // for caster applied auras only
403 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
404 (*i)->GetCasterGUID() != m_caster->GetGUID())
405 continue;
406
407 // Immolate
408 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
409 {
410 aura = *i; // it selected always if exist
411 break;
412 }
413
414 // Shadowflame
415 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
416 aura = *i; // remember but wait possible Immolate as primary priority
417 }
418
419 // found Immolate or Shadowflame
420 if (aura)
421 {
422 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
423 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
424 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
425 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
426
427 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
428
429 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
430 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
431
432 apply_direct_bonus = false;
433 // Glyph of Conflagrate
434 if (!m_caster->HasAura(56235))
436
437 break;
438 }
439 }
440 // Shadow Bite
441 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
442 {
444 {
445 if (Player* owner = m_caster->GetOwner()->ToPlayer())
446 {
447 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
448 {
449 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
450 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
451 }
452 }
453 }
454 }
455 break;
456 }
458 {
459 // Improved Mind Blast (Mind Blast in shadow form bonus)
460 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
461 {
463 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
464 {
465 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
466 ((*i)->GetSpellInfo()->SpellIconID == 95))
467 {
468 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
469 if (roll_chance_i(chance))
470 // Mind Trauma
471 m_caster->CastSpell(unitTarget, 48301, true, 0);
472 break;
473 }
474 }
475 }
476 break;
477 }
479 {
480 // Ferocious Bite
481 if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
482 {
483 // converts each extra point of energy into ($f1+$AP/410) additional damage
485 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
486 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
487 damage += int32(energy * multiple);
489 }
490 // Wrath
491 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
492 {
493 // Improved Insect Swarm
494 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
496 AddPct(damage, aurEff->GetAmount());
497 }
498 break;
499 }
501 {
502 // Envenom
503 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
504 {
505 if (Player* player = m_caster->ToPlayer())
506 {
507 // consume from stack dozes not more that have combo-points
508 if (uint32 combo = player->GetComboPoints())
509 {
510 // Lookup for Deadly poison (only attacker applied)
512 {
513 // count consumed deadly poison doses at target
514 bool needConsume = true;
515 uint32 spellId = aurEff->GetId();
516
517 uint32 doses = aurEff->GetBase()->GetStackAmount();
518 if (doses > combo)
519 doses = combo;
520
521 // Master Poisoner
522 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
523 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
524 {
525 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
526 {
527 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
528
529 if (chance && roll_chance_i(chance))
530 needConsume = false;
531
532 break;
533 }
534 }
535
536 if (needConsume)
537 for (uint32 i = 0; i < doses; ++i)
539
540 damage *= doses;
541 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
542 }
543
544 // Eviscerate and Envenom Bonus Damage (item set effect)
545 if (m_caster->HasAura(37169))
546 damage += combo * 40;
547 }
548 }
549 }
550 // Eviscerate
551 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
552 {
554 {
555 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
556 {
558 damage += int32(ap * combo * 0.07f);
559
560 // Eviscerate and Envenom Bonus Damage (item set effect)
561 if (m_caster->HasAura(37169))
562 damage += combo * 40;
563 }
564 }
565 }
566 break;
567 }
569 {
570 //Gore
571 if (m_spellInfo->SpellIconID == 1578)
572 {
573 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
574 damage *= 2;
575 }
576 // Steady Shot
577 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
578 {
579 bool found = false;
580 // check dazed affect
582 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
583 {
584 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
585 {
586 found = true;
587 break;
588 }
589 }
590
592 if (found)
593 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
594
595 if (Player* caster = m_caster->ToPlayer())
596 {
597 // Add Ammo and Weapon damage plus RAP * 0.1
598 float dmg_min = 0.f;
599 float dmg_max = 0.f;
600 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
601 {
602 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
603 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
604 }
605
606 if (dmg_max == 0.0f && dmg_min > dmg_max)
607 {
608 damage += int32(dmg_min);
609 }
610 else
611 {
612 damage += irand(int32(dmg_min), int32(dmg_max));
613 }
614 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
615 }
616 }
617 break;
618 }
620 {
621 // Hammer of the Righteous
622 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
623 {
624 // Add main hand dps * effect[2] amount
625 if (Player* player = m_caster->ToPlayer())
626 {
627 float minTotal = 0.f;
628 float maxTotal = 0.f;
629 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
630 {
631 float tmpMin, tmpMax;
632 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
633 minTotal += tmpMin;
634 maxTotal += tmpMax;
635 }
636
637 float average = (minTotal + maxTotal) / 2;
640 }
641 break;
642 }
643 // Shield of Righteousness
644 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
645 {
646 uint8 level = m_caster->getLevel();
647 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
648 if (m_caster->GetAuraEffect(64882, EFFECT_0))
649 block_value += 225;
650 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
651 break;
652 }
653 break;
654 }
655 }
656
657 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
658 {
659 // Xinef: protection
660 if (damage < 0)
661 damage = 0;
662
665 }
666
667 m_damage += damage;
668 }
669}
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:622
@ MINDAMAGE
Definition: Unit.h:254
@ MAXDAMAGE
Definition: Unit.h:255
@ FORM_SHADOW
Definition: Unit.h:116
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition: SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition: SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition: SpellAuraDefines.h:96
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition: SpellInfo.h:179
@ EFFECT_2
Definition: SharedDefines.h:32
@ POWER_ENERGY
Definition: SharedDefines.h:244
@ SPELLFAMILY_PRIEST
Definition: SharedDefines.h:3506
@ AURA_STATE_CONFLAGRATE
Definition: SharedDefines.h:1278
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition: Unit.cpp:16141
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition: Unit.cpp:15542
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:5647
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.h:1467
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition: Unit.h:2220
uint8 GetStackAmount() const
Definition: SpellAuras.h:148

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::getLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), Object::GetTypeId(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Unit::IsPet(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3800{
3802 return;
3803
3805
3807 {
3809 {
3810 switch (m_spellInfo->Id)
3811 {
3812 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3813 case 22539:
3814 case 22972:
3815 case 22975:
3816 case 22976:
3817 case 22977:
3818 case 22978:
3819 case 22979:
3820 case 22980:
3821 case 22981:
3822 case 22982:
3823 case 22983:
3824 case 22984:
3825 case 22985:
3826 {
3827 if (!unitTarget || !unitTarget->IsAlive())
3828 return;
3829
3830 // Onyxia Scale Cloak
3831 if (unitTarget->HasAura(22683))
3832 return;
3833
3834 // Shadow Flame
3835 m_caster->CastSpell(unitTarget, 22682, true);
3836 return;
3837 }
3838 // Plant Warmaul Ogre Banner
3839 case 32307:
3840 if (Player* caster = m_caster->ToPlayer())
3841 {
3842 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3843 if (Creature* target = unitTarget->ToCreature())
3844 {
3845 target->setDeathState(CORPSE);
3846 target->RemoveCorpse();
3847 }
3848 }
3849 break;
3850 // SOTA defender teleport
3851 case 54640:
3852 {
3853 if (Player* player = unitTarget->ToPlayer())
3854 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3855 {
3856 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3857 {
3858 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3859 bg->DefendersPortalTeleport(dportal, player);
3860 }
3861 }
3862 return;
3863 }
3864 /*// Mug Transformation
3865 case 41931:
3866 {
3867 if (m_caster->GetTypeId() != TYPEID_PLAYER)
3868 return;
3869
3870 uint8 bag = 19;
3871 uint8 slot = 0;
3872 Item* item = nullptr;
3873
3874 while (bag) // 256 = 0 due to var type
3875 {
3876 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3877 if (item && item->GetEntry() == 38587)
3878 break;
3879
3880 ++slot;
3881 if (slot == 39)
3882 {
3883 slot = 0;
3884 ++bag;
3885 }
3886 }
3887 if (bag)
3888 {
3889 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3890 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3891 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3892 m_caster->CastSpell(m_caster, 42518, true);
3893 return;
3894 }
3895 break;
3896 }*/
3897 // Roll Dice - Decahedral Dwarven Dice
3898 case 47770:
3899 {
3900 char buf[128];
3901 const char* gender = "his";
3902 if (m_caster->getGender() > 0)
3903 gender = "her";
3904 sprintf(buf, "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3905 m_caster->TextEmote(buf);
3906 break;
3907 }
3908 // Roll 'dem Bones - Worn Troll Dice
3909 case 47776:
3910 {
3911 char buf[128];
3912 const char* gender = "his";
3913 if (m_caster->getGender() > 0)
3914 gender = "her";
3915 sprintf(buf, "%s causually tosses %s [Worn Troll Dice]. One %u and one %u.", m_caster->GetName().c_str(), gender, urand(1, 6), urand(1, 6));
3916 m_caster->TextEmote(buf);
3917 break;
3918 }
3919 case 52173: // Coyote Spirit Despawn
3920 case 60243: // Blood Parrot Despawn
3923 return;
3924 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3925 {
3927 return;
3928
3930
3931 return;
3932 }
3933 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3934 {
3936 return;
3937
3938 // Delete item from inventory at death
3940
3941 return;
3942 }
3943 case 58418: // Portal to Orgrimmar
3944 case 58420: // Portal to Stormwind
3945 {
3946 if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || effIndex != 0)
3947 return;
3948
3949 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3950 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3951
3953 unitTarget->CastSpell(unitTarget, spellID, true);
3954
3955 return;
3956 }
3957 // Stoneclaw Totem
3958 case 55328: // Rank 1
3959 case 55329: // Rank 2
3960 case 55330: // Rank 3
3961 case 55332: // Rank 4
3962 case 55333: // Rank 5
3963 case 55335: // Rank 6
3964 case 55278: // Rank 7
3965 case 58589: // Rank 8
3966 case 58590: // Rank 9
3967 case 58591: // Rank 10
3968 {
3969 int32 basepoints0 = damage;
3970 // Cast Absorb on totems
3971 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
3972 {
3973 if (!unitTarget->m_SummonSlot[slot])
3974 continue;
3975
3977 if (totem && totem->IsTotem())
3978 {
3979 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3980 }
3981 }
3982 // Glyph of Stoneclaw Totem
3983 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3984 {
3985 basepoints0 *= aur->GetAmount();
3986 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3987 }
3988 break;
3989 }
3990 case 61263: // for item Intravenous Healing Potion (44698)
3991 {
3992 if( !m_caster || !unitTarget )
3993 return;
3994
3995 m_caster->CastSpell(m_caster, 61267, true);
3996 m_caster->CastSpell(m_caster, 61268, true);
3997 return;
3998 }
3999 }
4000 break;
4001 }
4002 case SPELLFAMILY_ROGUE:
4003 {
4004 switch( m_spellInfo->Id )
4005 {
4006 // Master of Subtlety
4007 case 31666:
4008 {
4009 if( !unitTarget )
4010 return;
4011
4012 Aura* mos = unitTarget->GetAura(31665);
4013 if( mos )
4014 {
4015 mos->SetMaxDuration(6000);
4016 mos->SetDuration(6000, true);
4017 }
4018
4019 break;
4020 }
4021 // Overkill
4022 case 58428:
4023 {
4024 if( !unitTarget )
4025 return;
4026
4027 Aura* overkill = unitTarget->GetAura(58427);
4028 if( overkill )
4029 {
4030 overkill->SetMaxDuration(20000);
4031 overkill->SetDuration(20000, true);
4032 }
4033
4034 break;
4035 }
4036 }
4037 break;
4038 }
4039 }
4040
4041 // normal DB scripted effect
4042 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4044}
@ CORPSE
Definition: Unit.h:318
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:101
@ BATTLEGROUND_SA
Definition: SharedDefines.h:3461
Class for manage Strand of Ancient battleground.
Definition: BattlegroundSA.h:456
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition: BattlegroundSA.cpp:575
void DespawnOrUnsummon(Milliseconds msTimeToDespawn, Seconds forcedRespawnTimer)
Despawn or Unsummon creature. If creature is a TempSummon it will be unsummoned.
Definition: Creature.cpp:2154
virtual void UnSummon(uint32 msTime=0)
Definition: TemporarySummon.cpp:270
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition: Object.cpp:2403
std::string const & GetName() const
Definition: Object.h:446
uint8 getGender() const
Definition: Unit.h:1426
bool IsSummon() const
Definition: Unit.h:1410
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition: Unit.cpp:22009

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), CORPSE, damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Object::GetTypeId(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, TYPEID_UNIT, unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4877{
4879 return;
4880
4881 if (!m_caster || m_caster->IsAlive())
4882 return;
4884 return;
4885 if (!m_caster->IsInWorld())
4886 return;
4887
4888 uint32 health = 0;
4889 uint32 mana = 0;
4890
4891 // flat case
4892 if (damage < 0)
4893 {
4894 health = uint32(-damage);
4895 mana = m_spellInfo->Effects[effIndex].MiscValue;
4896 }
4897 // percent case
4898 else
4899 {
4903 }
4904
4905 Player* player = m_caster->ToPlayer();
4906 player->ResurrectPlayer(0.0f);
4907
4908 player->SetHealth(health);
4909 player->SetPower(POWER_MANA, mana);
4910 player->SetPower(POWER_RAGE, 0);
4911 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4912
4913 player->SpawnCorpseBones();
4914}
@ POWER_RAGE
Definition: SharedDefines.h:242
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4573
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4361
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:16279

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Object::GetTypeId(), Unit::IsAlive(), Object::IsInWorld(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1400{
1401 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1404 return;
1405
1406 WorldObject* target = nullptr;
1407
1408 // call events for object target if present
1410 {
1411 if (unitTarget)
1412 target = unitTarget;
1413 else if (gameObjTarget)
1414 target = gameObjTarget;
1415 }
1416 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1417 {
1418 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1419 // this check was requested by scripters, but it has some downsides:
1420 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1421 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1422 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1423 return;
1424 // some spells have no target entries in dbc and they use focus target
1425 if (focusObject)
1426 target = focusObject;
1428 }
1429
1430 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1431
1432 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1433 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1434 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1435 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1436
1437 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1438}
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:58
@ TARGET_FLAG_UNIT_MASK
Definition: SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellInfo.h:70
Definition: Object.h:393
ZoneScript * GetZoneScript() const
Definition: Object.h:523
Definition: ZoneScript.h:27

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5153{
5155 return;
5156
5157 if (!unitTarget)
5158 return;
5159
5160 Player* player = unitTarget->ToPlayer();
5161 if (!player)
5162 {
5163 return;
5164 }
5165
5166 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5167}
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=1)
Definition: Player.cpp:9962

References Player::ActivateTaxiPathTo(), effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5593{
5595 return;
5596
5597 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5598}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4917{
4919 return;
4920
4922 return;
4924 return;
4925
4926 Creature* creature = unitTarget->ToCreature();
4927 int32 targetLevel = creature->getLevel();
4928
4929 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4930
4934
4935 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4936
4937 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4938
4939 // Double chances for elites
4940 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4941}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3093
bool isElite() const
Definition: Creature.h:105
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:117

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::getLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::GetTypeId(), Creature::isElite(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5624{
5626 return;
5627
5628 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5630 return;
5631
5633}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7600

References effectHandleMode, Object::GetTypeId(), Unit::IsAlive(), LOG_DEBUG, m_caster, Player::RemovedInsignia(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6199{
6201 return;
6202
6203 if (!unitTarget)
6204 return;
6205
6206 Player* player = unitTarget->ToPlayer();
6207 if (!player)
6208 {
6209 return;
6210 }
6211
6212 player->UpdateSpecCount(damage);
6213}
void UpdateSpecCount(uint8 count)
Definition: PlayerUpdates.cpp:2142

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and Player::UpdateSpecCount().

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5605{
5607 return;
5608
5609 /*
5610 if (unitTarget->GetTypeId() != TYPEID_PLAYER)
5611 return;
5612 if (!unitTarget->IsInWorld())
5613 return;
5614
5615 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5616 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5617 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5618 unitTarget->ToPlayer()->SpawnCorpseBones();
5619 */
5620}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5636{
5638 return;
5639
5640 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5641
5642 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5643 return;
5644
5645 DispelChargesList steal_list;
5646
5647 // Create dispel mask by dispel type
5648 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5649 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5650 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5651 {
5652 Aura* aura = itr->second;
5654 if (!aurApp)
5655 continue;
5656
5657 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5658 {
5659 // Need check for passive? this
5660 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5661 continue;
5662
5663 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5664 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5665 // Polymorph instead of 1 / (5 + 1) -> 16%.
5666 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5667 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5668 if (charges > 0)
5669 steal_list.push_back(std::make_pair(aura, charges));
5670 }
5671 }
5672
5673 if (steal_list.empty())
5674 return;
5675
5676 // Ok if exist some buffs for dispel try dispel it
5677 uint32 failCount = 0;
5678 DispelList success_list;
5679 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5680 // dispel N = damage buffs (or while exist buffs for dispel)
5681 for (int32 count = 0; count < damage && !steal_list.empty();)
5682 {
5683 // Random select buff for dispel
5684 DispelChargesList::iterator itr = steal_list.begin();
5685 std::advance(itr, urand(0, steal_list.size() - 1));
5686
5687 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5688 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5689 if (!chance)
5690 {
5691 steal_list.erase(itr);
5692 continue;
5693 }
5694 else
5695 {
5696 if (roll_chance_i(chance))
5697 {
5698 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5699 --itr->second;
5700 if (itr->second <= 0)
5701 steal_list.erase(itr);
5702 }
5703 else
5704 {
5705 if (!failCount)
5706 {
5707 // Failed to dispell
5708 dataFail << m_caster->GetGUID(); // Caster GUID
5709 dataFail << unitTarget->GetGUID(); // Victim GUID
5710 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5711 }
5712 ++failCount;
5713 dataFail << uint32(itr->first->GetId()); // Spell Id
5714 }
5715 ++count;
5716 }
5717 }
5718
5719 if (failCount)
5720 m_caster->SendMessageToSet(&dataFail, true);
5721
5722 if (success_list.empty())
5723 return;
5724
5725 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5726 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5727 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5728 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5729 dataSuccess << uint8(0); // not used
5730 dataSuccess << uint32(success_list.size()); // count
5731 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5732 {
5733 dataSuccess << uint32(itr->first); // Spell Id
5734 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5735 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5736 }
5737 m_caster->SendMessageToSet(&dataSuccess, true);
5738}
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition: SpellEffects.cpp:2571
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition: SharedDefines.h:623
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition: SharedDefines.h:508
@ SMSG_SPELLSTEALLOG
Definition: Opcodes.h:849
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition: Unit.cpp:5735
bool IsPositive() const
Definition: SpellAuras.h:68
uint8 GetCharges() const
Definition: SpellAuras.h:141
bool IsPassive() const
Definition: SpellAuras.cpp:1098

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4216{
4218 return;
4219
4221 return;
4222
4223 Player* target = m_caster->ToPlayer();
4224 if (target->IsInFlight())
4225 return;
4226
4227 // xinef: if player is dead - teleport to graveyard
4228 if (!target->IsAlive())
4229 {
4231 return;
4232
4233 // xinef: player is in corpse
4234 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4235 target->BuildPlayerRepop();
4236 target->RepopAtGraveyard();
4237 return;
4238 }
4239
4240 // xinef: no hearthstone in bag or on cooldown
4241 Item* hearthStone = target->GetItemByEntry(6948);
4242 if (!hearthStone || target->HasSpellCooldown(8690))
4243 {
4244 float o = rand_norm() * 2 * M_PI;
4245 Position pos = *target;
4246 target->MovePositionToFirstCollision(pos, 5.0f, o);
4247 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4248 return;
4249 }
4250
4251 // xinef: we have hearthstone not on cooldown, just use it
4253}
double rand_norm()
Definition: Random.cpp:77
@ PLAYER_FLAGS_GHOST
Definition: Player.h:479
@ SPELL_AURA_PREVENT_RESURRECTION
Definition: SpellAuraDefines.h:377
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2806
void RepopAtGraveyard()
Definition: Player.cpp:4807
void BuildPlayerRepop()
Definition: Player.cpp:4312

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Object::GetTypeId(), Unit::HasAuraType(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_AURA_PREVENT_RESURRECTION, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, and TYPEID_PLAYER.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2210{
2212 return;
2213
2215 return;
2216
2217 Player* player = m_caster->ToPlayer();
2218
2219 // applied only to using item
2220 if (!m_CastItem)
2221 return;
2222
2223 // ... only to item in own inventory/bank/equip_slot
2224 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2225 return;
2226
2227 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2228 if (!newitemid)
2229 return;
2230
2231 uint16 pos = m_CastItem->GetPos();
2232
2233 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2234 if (!pNewItem)
2235 return;
2236
2237 // Client-side enchantment durations update
2239
2243
2245 {
2247 player->DurabilityLoss(pNewItem, lossPercent);
2248 }
2249
2250 if (player->IsInventoryPos(pos))
2251 {
2252 ItemPosCountVec dest;
2253 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2254 if (msg == EQUIP_ERR_OK)
2255 {
2256 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2257
2258 // prevent crash at access and unexpected charges counting with item update queue corrupt
2260 m_targets.SetItemTarget(nullptr);
2261
2262 m_CastItem = nullptr;
2264
2265 player->StoreItem(dest, pNewItem, true);
2266 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2267 return;
2268 }
2269 }
2270 else if (player->IsBankPos(pos))
2271 {
2272 ItemPosCountVec dest;
2273 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2274 if (msg == EQUIP_ERR_OK)
2275 {
2276 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2277
2278 // prevent crash at access and unexpected charges counting with item update queue corrupt
2280 m_targets.SetItemTarget(nullptr);
2281
2282 m_CastItem = nullptr;
2284
2285 player->BankItem(dest, pNewItem, true);
2286 return;
2287 }
2288 }
2289 else if (player->IsEquipmentPos(pos))
2290 {
2291 uint16 dest;
2292
2293 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2294
2295 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2296
2297 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2298 {
2300
2301 // prevent crash at access and unexpected charges counting with item update queue corrupt
2303 m_targets.SetItemTarget(nullptr);
2304
2305 m_CastItem = nullptr;
2307
2308 player->EquipItem(dest, pNewItem, true);
2309 player->AutoUnequipOffhandIfNeed();
2310 return;
2311 }
2312 }
2313
2314 // fail
2315 delete pNewItem;
2316}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:80
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
uint8 GetSlot() const
Definition: Item.h:272
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1089
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:296
uint16 GetPos() const
Definition: Item.h:276
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:297
uint8 GetBagSlot() const
Definition: Item.cpp:786
void Clear()
Definition: ObjectGuid.h:140
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1232
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1841
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1301
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1252
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4765
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2604
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3053
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1230
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12182
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2757
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2060
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1812
static bool IsBankPos(uint16 pos)
Definition: Player.h:1235

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetTypeId(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), TYPEID_PLAYER, and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4595{
4597 return;
4598
4599 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4600
4601 uint8 slot = 0;
4602 switch (m_spellInfo->Effects[effIndex].Effect)
4603 {
4605 slot = 0;
4606 break;
4608 slot = 1;
4609 break;
4611 slot = 2;
4612 break;
4614 slot = 3;
4615 break;
4616 default:
4617 return;
4618 }
4619
4620 if (m_caster)
4621 {
4622 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4623 if (guid)
4624 {
4625 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4626 {
4627 // Recast case - null spell id to make auras not be removed on object remove from world
4628 if (m_spellInfo->Id == gameObject->GetSpellId())
4629 gameObject->SetSpellId(0);
4630 m_caster->RemoveGameObject(gameObject, true);
4631 }
4632 m_caster->m_ObjectSlot[slot].Clear();
4633 }
4634 }
4635
4636 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4637
4638 float x, y, z;
4639 // If dest location if present
4640 if (m_targets.HasDst())
4641 destTarget->GetPosition(x, y, z);
4642 // Summon in random point all other units if location present
4643 else
4645
4646 Map* map = m_caster->GetMap();
4647 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4648 {
4649 delete pGameObj;
4650 return;
4651 }
4652
4653 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
4654 int32 duration = m_spellInfo->GetDuration();
4655 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4656 pGameObj->SetSpellId(m_spellInfo->Id);
4657 m_caster->AddGameObject(pGameObj);
4658
4659 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4660
4661 map->AddToMap(pGameObj, true);
4662
4663 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4664}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition: ObjectDefines.h:45
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition: SharedDefines.h:857
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition: SharedDefines.h:854
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition: SharedDefines.h:856
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition: SharedDefines.h:855
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition: Unit.h:2319

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3750{
3752 return;
3753
3754 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3755
3756 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3757
3758 WorldObject* target = focusObject;
3759 if (!target)
3760 target = m_caster;
3761
3762 float x, y, z;
3763 if (m_targets.HasDst())
3764 destTarget->GetPosition(x, y, z);
3765 else
3767
3768 Map* map = target->GetMap();
3769
3770 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3771 {
3772 delete pGameObj;
3773 return;
3774 }
3775
3776 int32 duration = m_spellInfo->GetDuration();
3777
3778 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3779 pGameObj->SetSpellId(m_spellInfo->Id);
3780
3781 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3782
3783 // Wild object not have owner and check clickable by players
3784 map->AddToMap(pGameObj, true);
3785
3786 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3787 if (Player* player = m_caster->ToPlayer())
3788 if (Battleground* bg = player->GetBattleground())
3789 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3790
3791 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3792 {
3793 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3794 linkedTrap->SetSpellId(m_spellInfo->Id);
3795 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3796 }
3797}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition: SharedDefines.h:1558
@ TEAM_ALLIANCE
Definition: SharedDefines.h:732
@ TEAM_HORDE
Definition: SharedDefines.h:733
GameObject * GetLinkedTrap()
Definition: GameObject.cpp:2754
GameobjectTypes GetGoType() const
Definition: GameObject.h:896

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3156{
3158 return;
3159
3160 if (!m_originalCaster)
3161 return;
3162
3163 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3164 int32 duration = m_spellInfo->GetDuration();
3165
3166 if(Player* modOwner = m_originalCaster->GetSpellModOwner())
3167 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3168
3169 Player* owner = m_originalCaster->ToPlayer();
3170 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3172
3173 if (!owner)
3174 {
3175 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3176 if (properties)
3177 {
3178 // Xinef: unsummon old guardian
3179 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3180 oldPet->UnSummon();
3181 SummonGuardian(effIndex, petentry, properties, 1);
3182 }
3183 return;
3184 }
3185
3186 Pet* OldSummon = owner->GetPet();
3187
3188 // if pet requested type already exist
3189 if (OldSummon)
3190 {
3191 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3192 {
3193 // pet in corpse state can't be summoned
3194 if (OldSummon->isDead())
3195 return;
3196
3197 ASSERT(OldSummon->GetMap() == owner->GetMap());
3198
3199 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3200
3201 float px, py, pz;
3202 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3203
3204 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3205 OldSummon->UpdateObjectVisibility();
3206
3207 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3208 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3209 // notify player
3210 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3211 owner->SendClearCooldown(itr->first, OldSummon);
3212
3213 // actually clear cooldowns
3214 OldSummon->m_CreatureSpellCooldowns.clear();
3215 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3216 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3217 {
3218 Aura const* aura = i->second->GetBase();
3219 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3220 OldSummon->RemoveAura(i);
3221 else
3222 ++i;
3223 }
3224 return;
3225 }
3226
3227 if (owner->GetTypeId() == TYPEID_PLAYER)
3228 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3229 else
3230 return;
3231 }
3232
3233 float x, y, z;
3234 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3235 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3236 if (!pet)
3237 return;
3238
3239 if (m_caster->GetTypeId() == TYPEID_UNIT)
3240 {
3241 if (m_caster->ToCreature()->IsTotem())
3243 else
3245 }
3246
3248
3249 // Reset cooldowns
3250 if (owner->getClass() != CLASS_HUNTER)
3251 {
3252 pet->m_CreatureSpellCooldowns.clear();
3253 owner->PetSpellInitialize();
3254 }
3255
3256 // Set health to max if new pet is summoned
3257 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3258 // pet should have full health
3259 pet->SetHealth(pet->GetMaxHealth());
3260
3261 // generate new name for summon pet
3262 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3263 if (!new_name.empty())
3264 pet->SetName(new_name);
3265
3266 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3267}
@ REACT_DEFENSIVE
Definition: Unit.h:1024
@ REACT_AGGRESSIVE
Definition: Unit.h:1025
@ SPELLMOD_DURATION
Definition: SpellDefines.h:78
void SetReactState(ReactStates st)
Definition: Creature.h:88
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:242
Definition: TemporarySummon.h:90
void SetName(std::string const &newname)
Definition: Object.h:447
float GetObjectSize() const
Definition: Object.cpp:2719
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14345
bool IsPetAura(Aura const *aura)
Definition: Unit.cpp:18242
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: Unit.cpp:20018
bool isDead() const
Definition: Unit.h:2026
bool CanBeSentToClient() const
Definition: SpellAuras.cpp:1153
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons)
Definition: SpellEffects.cpp:6010

References ASSERT, Aura::CanBeSentToClient(), CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Unit::getClass(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellInfo::Id, Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Object::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4256{
4257 // workaround - this effect should not use target map
4259 return;
4260
4261 if (!unitTarget)
4262 return;
4263
4264 Player* player = unitTarget->ToPlayer();
4265 if (!player)
4266 {
4267 return;
4268 }
4269
4270 // Evil Twin (ignore player summon, but hide this for summoner)
4271 // Xinef: Unit Target may be on other map!!!, Need workaround
4272 if (unitTarget->HasAura(23445))
4273 return;
4274
4275 float x, y, z;
4276 m_caster->GetPosition(x, y, z);
4277
4278 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4279
4280 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4281 data << m_caster->GetGUID(); // summoner guid
4282 data << uint32(m_caster->GetZoneId()); // summoner zone
4283 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4284 player->GetSession()->SendPacket(&data);
4285}
#define MAX_PLAYER_SUMMON_DELAY
Definition: Player.h:921
@ SMSG_SUMMON_REQUEST
Definition: Opcodes.h:713
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition: Player.cpp:16009

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6399{
6401 return;
6402
6404 return;
6405
6406 if (!unitTarget)
6407 return;
6408
6409 Player* player = unitTarget->ToPlayer();
6410 if (!player)
6411 {
6412 return;
6413 }
6414
6415 float x, y, z;
6416 m_caster->GetPosition(x, y, z);
6418 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6419 data << m_caster->GetGUID();
6420 data << uint32(m_caster->GetZoneId());
6421 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6422 player->GetSession()->SendPacket(&data);
6423}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), Object::GetTypeId(), WorldObject::GetZoneId(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2341{
2343 return;
2344
2345 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2346 if (!entry)
2347 return;
2348
2349 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2350 if (!properties)
2351 {
2352 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2353 return;
2354 }
2355
2356 if (!m_originalCaster)
2357 return;
2358
2359 int32 duration = m_spellInfo->GetDuration();
2360 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2361 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2362
2363 TempSummon* summon = nullptr;
2364
2365 // determine how many units should be summoned
2366 uint32 numSummons;
2367
2368 // some spells need to summon many units, for those spells number of summons is stored in effect value
2369 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2370 // and in spell attributes, possibly we need to add a table for those)
2371 // so here's a list of MiscValueB values, which is currently most generic check
2372 switch (properties->Id)
2373 {
2374 case 64:
2375 case 61:
2376 case 1101:
2377 case 66:
2378 case 648:
2379 case 2301:
2380 case 1061:
2381 case 1261:
2382 case 629:
2383 case 181:
2384 case 715:
2385 case 1562:
2386 case 833:
2387 case 1161:
2388 case 713: // xinef, bloodworms
2389 numSummons = (damage > 0) ? damage : 1;
2390 break;
2391 default:
2392 numSummons = 1;
2393 break;
2394 }
2395
2396 switch (properties->Category)
2397 {
2401 if (properties->Flags & 512)
2402 {
2403 SummonGuardian(effIndex, entry, properties, numSummons);
2404 break;
2405 }
2406 switch (properties->Type)
2407 {
2408 case SUMMON_TYPE_PET:
2411 case SUMMON_TYPE_MINION:
2412 SummonGuardian(effIndex, entry, properties, numSummons);
2413 break;
2414 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2417 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
2418 break;
2420 case SUMMON_TYPE_TOTEM:
2421 {
2422 // protection code
2423 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
2424 if (!summon || !summon->IsTotem())
2425 return;
2426
2427 // Mana Tide Totem
2428 if (m_spellInfo->Id == 16190)
2430
2431 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2432 {
2433 summon->SetMaxHealth(damage);
2434 summon->SetHealth(damage);
2435 }
2436 break;
2437 }
2438 case SUMMON_TYPE_JEEVES:
2440 {
2441 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
2442 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2443 return;
2444
2445 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2447
2448 summon->SetImmuneToAll(true);
2450
2451 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2452 //summon->AI()->EnterEvadeMode();
2453 if (properties->Type != SUMMON_TYPE_JEEVES)
2454 {
2455 summon->GetMotionMaster()->Clear(false);
2457 }
2458 break;
2459 }
2460 default:
2461 {
2462 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2463
2464 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2465
2466 for (uint32 count = 0; count < numSummons; ++count)
2467 {
2468 Position pos;
2469 if (count == 0)
2470 pos = *destTarget;
2471 else
2472 // randomize position for multiple summons
2473 pos = m_caster->GetRandomPoint(*destTarget, radius);
2474
2475 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration);
2476 if (!summon)
2477 continue;
2478
2479 summon->SetTempSummonType(summonType);
2480
2481 if (properties->Category == SUMMON_CATEGORY_ALLY)
2482 {
2485 }
2486
2487 ExecuteLogEffectSummonObject(effIndex, summon);
2488 }
2489 return;
2490 }
2491 }//switch
2492 break;
2494 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2495 if (m_originalCaster)
2497 SummonGuardian(effIndex, entry, properties, numSummons);
2498 break;
2500 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
2501 break;
2503 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2504 // to cast a ride vehicle spell on the summoned unit.
2505 //float x, y, z;
2506 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2507 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2508 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2510
2511 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id);
2512 if (!summon || !summon->IsVehicle())
2513 return;
2514
2515 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2517 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2518 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2519 {
2520 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2521 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2522 spellId = spellInfo->Id;
2523 }
2524
2525 // xinef: if we have small value, it indicates seat position
2526 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2527 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2528 else
2529 m_originalCaster->CastSpell(summon, spellId, true);
2530
2531 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2532 //uint32 faction = properties->Faction;
2533 //if (!faction)
2534 uint32 faction = m_originalCaster->GetFaction();
2535
2536 summon->SetFaction(faction);
2537 break;
2538 }
2539
2540 if (summon)
2541 {
2543 ExecuteLogEffectSummonObject(effIndex, summon);
2544 }
2545}
TempSummonType
Definition: Object.h:41
@ TEMPSUMMON_DEAD_DESPAWN
Definition: Object.h:48
@ UNIT_MASK_MINION
Definition: Unit.h:676
@ REACT_PASSIVE
Definition: Unit.h:1023
NPCFlags
Non Player Character flags.
Definition: Unit.h:514
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:53
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:62
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
#define MAX_VEHICLE_SEATS
Definition: DBCStructure.h:1986
@ SUMMON_TYPE_VEHICLE2
Definition: SharedDefines.h:3276
@ SUMMON_TYPE_LIGHTWELL
Definition: SharedDefines.h:3277
@ SUMMON_TYPE_MINION
Definition: SharedDefines.h:3269
@ SUMMON_TYPE_GUARDIAN
Definition: SharedDefines.h:3268
@ SUMMON_TYPE_JEEVES
Definition: SharedDefines.h:3278
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3267
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3270
@ SUMMON_TYPE_VEHICLE
Definition: SharedDefines.h:3275
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3271
@ SUMMON_TYPE_GUARDIAN2
Definition: SharedDefines.h:3272
@ SUMMON_CATEGORY_VEHICLE
Definition: SharedDefines.h:3259
@ SUMMON_CATEGORY_ALLY
Definition: SharedDefines.h:3256
@ SUMMON_CATEGORY_WILD
Definition: SharedDefines.h:3255
@ SUMMON_CATEGORY_UNK
Definition: SharedDefines.h:3260
void SelectLevel(bool changelevel=true)
Definition: Creature.cpp:1479
uint32 npcflag
Definition: CreatureData.h:192
void SetTempSummonType(TempSummonType type)
Definition: TemporarySummon.cpp:265
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1504
void SetFaction(uint32 faction)
Definition: Unit.cpp:10873
virtual float GetFollowAngle() const
Definition: Unit.h:2660
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:11377
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:1407
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:16241
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:2033
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:1685
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:11667
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition: Unit.h:1714
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0)
Definition: Object.cpp:2117
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
Definition: MotionMaster.cpp:367
void Clear(bool reset=true)
Definition: MotionMaster.h:165
uint32 Flags
Definition: DBCStructure.h:1877
uint32 Type
Definition: DBCStructure.h:1875
uint32 Id
Definition: DBCStructure.h:1872

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, MAX_VEHICLE_SEATS, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3100{
3102 return;
3103
3104 if (m_caster->GetPetGUID())
3105 return;
3106
3107 if (!unitTarget)
3108 return;
3109
3111 return;
3112
3113 Creature* creatureTarget = unitTarget->ToCreature();
3114
3115 if (creatureTarget->IsPet())
3116 return;
3117
3118 if (m_caster->getClass() != CLASS_HUNTER)
3119 return;
3120
3121 // cast finish successfully
3122 //SendChannelUpdate(0);
3123 finish();
3124
3125 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3126 if (!pet) // in very specific state like near world end/etc.
3127 return;
3128
3129 // "kill" original creature
3130 creatureTarget->DespawnOrUnsummon();
3131
3132 uint8 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel();
3133
3134 // prepare visual effect for levelup
3135 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3136
3137 // add to world
3138 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3139
3140 // visual effect for levelup
3141 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3142
3143 // caster have pet now
3144 m_caster->SetMinion(pet, true);
3145
3146 pet->InitTalentForLevel();
3147
3149 {
3152 }
3153}
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

References Map::AddToMap(), CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::getClass(), Unit::getLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), Object::GetTypeId(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsPet(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Object::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3296{
3298 return;
3299
3300 if (!unitTarget)
3301 return;
3302
3303 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3304 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3305 {
3306 m_caster->CastSpell(unitTarget, 67485, true);
3308 }
3309
3310 // this effect use before aura Taunt apply for prevent taunt already attacking target
3311 // for spell as marked "non effective at already attacking target"
3313 {
3315 return;
3316 }
3317
3319 {
3320 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3321 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3323 if (topThreat > myThreat)
3324 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3325
3326 //Set aggro victim to caster
3328 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3329 }
3330
3333}
@ SPELL_AURA_MOD_TAUNT
Definition: SpellAuraDefines.h:74
Definition: ThreatMgr.h:49
float GetThreat() const
Definition: ThreatMgr.h:63
HostileReference * getMostHated() const
Definition: ThreatMgr.h:169
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition: ThreatMgr.cpp:262
bool empty() const
Definition: ThreatMgr.h:164
void setCurrentVictim(HostileReference *hostileRef)
Definition: ThreatMgr.cpp:557
void DoAddThreat(Unit *victim, float threat)
Definition: ThreatMgr.cpp:454
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition: ThreatMgr.cpp:510
ThreatContainer & GetOnlineContainer()
Definition: ThreatMgr.h:273
bool HasReactState(ReactStates state) const
Definition: Creature.h:90
bool CanHaveThreatList() const
Definition: Unit.cpp:15340

References Creature::AI(), UnitAI::AttackStart(), Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), Creature::HasReactState(), SpellInfo::Id, Unit::IsAIEnabled, m_caster, m_spellInfo, REACT_PASSIVE, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, Object::ToCreature(), and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1191{
1193 return;
1194
1195 if (!unitTarget || unitTarget->IsInFlight())
1196 return;
1197
1199 {
1200 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1201 }
1202
1203 // Pre effects
1204 switch (m_spellInfo->Id)
1205 {
1206 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1207 if (Player* target = unitTarget->ToPlayer())
1208 {
1209 uint32 mapid = destTarget->GetMapId();
1210 float x, y, z, orientation;
1211 destTarget->GetPosition(x, y, z, orientation);
1212 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1213 }
1214 return;
1215 }
1216
1217 // If not exist data for dest location - return
1218 if (!m_targets.HasDst())
1219 {
1220 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1221 return;
1222 }
1223
1224 // Init dest coordinates
1225 uint32 mapid = destTarget->GetMapId();
1226 if (mapid == MAPID_INVALID)
1227 mapid = unitTarget->GetMapId();
1228 float x, y, z, orientation;
1229 destTarget->GetPosition(x, y, z, orientation);
1230 if (!orientation && m_targets.GetUnitTarget())
1231 orientation = m_targets.GetUnitTarget()->GetOrientation();
1232 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1233
1234 if (mapid == unitTarget->GetMapId())
1235 {
1236 if (unitTarget->GetVehicleKit()) // we are vehicle!
1237 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1238 else
1239 {
1241 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1242 if (unitTarget->GetTypeId() == TYPEID_PLAYER) // pussywizard: for units it's done inside NearTeleportTo
1244 }
1245 }
1246 else if (unitTarget->GetTypeId() == TYPEID_PLAYER)
1247 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1248 else
1249 {
1250 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1251 return;
1252 }
1253
1254 // post effects for TARGET_DEST_DB
1255 switch (m_spellInfo->Id)
1256 {
1257 // Dimensional Ripper - Everlook
1258 case 23442:
1259 {
1260 int32 r = irand(0, 119);
1261 if (r >= 70) // 7/12 success
1262 {
1263 if (r < 100) // 4/12 evil twin
1264 m_caster->CastSpell(m_caster, 23445, true);
1265 else // 1/12 fire
1266 m_caster->CastSpell(m_caster, 23449, true);
1267 }
1268 return;
1269 }
1270 // Ultrasafe Transporter: Toshley's Station
1271 case 36941:
1272 {
1273 if (roll_chance_i(50)) // 50% success
1274 {
1275 int32 rand_eff = urand(1, 7);
1276 switch (rand_eff)
1277 {
1278 case 1:
1279 // soul split - evil
1280 m_caster->CastSpell(m_caster, 36900, true);
1281 break;
1282 case 2:
1283 // soul split - good
1284 m_caster->CastSpell(m_caster, 36901, true);
1285 break;
1286 case 3:
1287 // Increase the size
1288 m_caster->CastSpell(m_caster, 36895, true);
1289 break;
1290 case 4:
1291 // Decrease the size
1292 m_caster->CastSpell(m_caster, 36893, true);
1293 break;
1294 case 5:
1295 // Transform
1296 {
1298 m_caster->CastSpell(m_caster, 36897, true);
1299 else
1300 m_caster->CastSpell(m_caster, 36899, true);
1301 break;
1302 }
1303 case 6:
1304 // chicken
1305 m_caster->CastSpell(m_caster, 36940, true);
1306 break;
1307 case 7:
1308 // evil twin
1309 m_caster->CastSpell(m_caster, 23445, true);
1310 break;
1311 }
1312 }
1313 return;
1314 }
1315 }
1316}
#define MAPID_INVALID
Definition: Position.h:248
@ TELE_TO_SPELL
Definition: Player.h:818
@ TELE_TO_GM_MODE
Definition: Player.h:814
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2058
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1313
Vehicle * GetVehicleKit() const
Definition: Unit.h:2621
void TeleportVehicle(float x, float y, float z, float ang)
Definition: Vehicle.cpp:550

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), TYPEID_PLAYER, unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3681{
3683 return;
3684
3685 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3686 return;
3687
3688 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3690 return;
3691
3693}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:15379

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5944{
5946 return;
5947
5949 {
5950 if (Aura* aur = m_caster->GetAura(49152))
5951 aur->RecalculateAmountOfEffects();
5952 else
5953 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5954
5956 }
5957}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:12854

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::GetTypeId(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2837{
2839 return;
2840
2842 return;
2843 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2844 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2845 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2846}

References effectHandleMode, Object::GetTypeId(), m_caster, SPELL_EFFECT_HANDLE_HIT, and TYPEID_PLAYER.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5409{
5411 return;
5412
5413 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5414
5415 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5416
5417 if (!goinfo)
5418 {
5419 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5420 return;
5421 }
5422
5423 float fx, fy, fz;
5424
5425 if (m_targets.HasDst())
5426 destTarget->GetPosition(fx, fy, fz);
5427 //FIXME: this can be better check for most objects but still hack
5428 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5429 {
5430 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5432 }
5433 else
5434 {
5435 //GO is always friendly to it's creator, get range for friends
5436 float min_dis = m_spellInfo->GetMinRange(true);
5437 float max_dis = m_spellInfo->GetMaxRange(true);
5438 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5439
5441 }
5442
5443 // Seaforium charge
5444 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5445 {
5446 fx = m_caster->GetPositionX();
5447 fy = m_caster->GetPositionY();
5448 fz = m_caster->GetPositionZ();
5449 }
5450
5451 Map* cMap = m_caster->GetMap();
5452 // if gameobject is summoning object, it should be spawned right on caster's position
5454 m_caster->GetPosition(fx, fy, fz);
5455
5456 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5457
5458 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5459 {
5460 delete pGameObj;
5461 return;
5462 }
5463
5464 int32 duration = m_spellInfo->GetDuration();
5465
5466 switch (goinfo->type)
5467 {
5469 {
5471 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5472
5473 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5474 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5475 int32 lastSec = 0;
5476 switch (urand(0, 2))
5477 {
5478 case 0:
5479 lastSec = 3;
5480 break;
5481 case 1:
5482 lastSec = 7;
5483 break;
5484 case 2:
5485 lastSec = 13;
5486 break;
5487 }
5488
5489 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5490 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5491
5492 break;
5493 }
5495 {
5497 {
5498 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5499 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5500 }
5501 break;
5502 }
5503 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5504 m_caster->AddGameObject(pGameObj);
5505 break;
5508 default:
5509 break;
5510 }
5511
5512 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5513
5514 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5515
5516 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
5517 pGameObj->SetSpellId(m_spellInfo->Id);
5518
5519 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5520
5521 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5522 //m_caster->AddGameObject(pGameObj);
5523 //m_ObjToDel.push_back(pGameObj);
5524
5525 cMap->AddToMap(pGameObj, true);
5526
5527 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5528 {
5529 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5530 linkedTrap->SetSpellId(m_spellInfo->Id);
5531 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5532
5533 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5534 }
5535
5536 if (Player* player = m_caster->ToPlayer())
5537 {
5538 player->SetCanTeleport(true);
5539 }
5540}
#define FISHING_BOBBER_READY_TIME
Definition: GameObject.h:810
@ UNIT_FIELD_CHANNEL_OBJECT
Definition: UpdateFields.h:93
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition: SharedDefines.h:1548
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition: SharedDefines.h:1550
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1535
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1557
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1549
void SetOwnerGUID(ObjectGuid owner)
Definition: GameObject.h:856
void AddUniqueUse(Player *player)
Definition: GameObject.cpp:897
float GetMinRange(bool positive=false) const
Definition: SpellInfo.cpp:2294

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Object::GetTypeId(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, TYPEID_PLAYER, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
969{
972 return;
973
974 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
975
976 // normal case
977 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
978 if (!spellInfo)
979 {
980 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
981 return;
982 }
983
984 SpellCastTargets targets;
986 {
987 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
988 return;
989 targets.SetUnitTarget(unitTarget);
990 }
991 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
992 {
993 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
994 return;
995
997 targets.SetDst(m_targets);
998
999 targets.SetUnitTarget(m_caster);
1000 }
1001
1002 CustomSpellValues values;
1003 // set basepoints for trigger with value effect
1005 {
1006 // maybe need to set value only when basepoints == 0?
1010 }
1011
1012 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
1013 if (m_caster->GetTypeId() == TYPEID_PLAYER && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
1014 {
1015 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
1016 }
1017
1018 // original caster guid only for GO cast
1019 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
1020}
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition: SharedDefines.h:898
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition: SpellInfo.cpp:1021
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:347

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), Object::GetTypeId(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TYPEID_PLAYER, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1077{
1079 return;
1080
1081 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1082 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1083
1084 if (!spellInfo)
1085 {
1086 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1087 return;
1088 }
1089
1090 finish();
1091
1092 m_caster->CastSpell((Unit*)nullptr, spellInfo, false);
1093}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
795{
798 return;
799
800 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
801
803 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
805 {
806 // special cases
807 switch (triggered_spell_id)
808 {
809 // Mirror Image
810 case 58832:
811 {
812 // Glyph of Mirror Image
813 if (m_caster->HasAura(63093))
814 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
815
816 break;
817 }
818 // Vanish (not exist)
819 case 18461:
820 {
823
824 // See if we already are stealthed. If so, we're done.
825 if (unitTarget->HasAura(1784))
826 return;
827
828 // Reset cooldown on stealth if needed
831
832 unitTarget->CastSpell(unitTarget, 1784, true);
833 return;
834 }
835 // Demonic Empowerment -- succubus
836 case 54437:
837 {
841
842 // Cast Lesser Invisibility
843 unitTarget->CastSpell(unitTarget, 7870, true);
844 return;
845 }
846 // just skip
847 case 23770: // Sayge's Dark Fortune of *
848 // not exist, common cooldown can be implemented in scripts if need.
849 return;
850 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
851 case 29284:
852 {
853 // Brittle Armor
854 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
855 if (!spell)
856 return;
857
858 for (uint32 j = 0; j < spell->StackAmount; ++j)
859 m_caster->CastSpell(unitTarget, spell->Id, true);
860 return;
861 }
862 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
863 case 29286:
864 {
865 // Mercurial Shield
866 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
867 if (!spell)
868 return;
869
870 for (uint32 j = 0; j < spell->StackAmount; ++j)
871 m_caster->CastSpell(unitTarget, spell->Id, true);
872 return;
873 }
874 // Cloak of Shadows
875 case 35729:
876 {
879 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
880 {
881 // remove all harmful spells on you...
882 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
883
884 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
885 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
886 return;
887
888 bool dmgClassNone = false;
890 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
891 {
892 if ((iter->second->GetEffectMask() & (1 << i)) &&
893 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
894 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
895 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
896 {
897 dmgClassNone = false;
898 break;
899 }
900 dmgClassNone = true;
901 }
902
903 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
904 // ignore positive and passive auras
905 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
906 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
908 {
909 m_caster->RemoveAura(iter);
910 }
911 else
912 ++iter;
913 }
914 return;
915 }
916 }
917 }
918
919 // normal case
920 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
921 if (!spellInfo)
922 {
923 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
924 return;
925 }
926
927 SpellCastTargets targets;
929 {
930 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
931 return;
932 targets.SetUnitTarget(unitTarget);
933 }
934 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
935 {
936 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
937 return;
938
940 targets.SetDst(m_targets);
941
942 if (Unit* target = m_targets.GetUnitTarget())
943 targets.SetUnitTarget(target);
944 else
945 targets.SetUnitTarget(m_caster);
946 }
947
948 CustomSpellValues values;
949 // set basepoints for trigger with value effect
951 {
952 // maybe need to set value only when basepoints == 0?
956 }
957
958 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
959 if (m_caster->GetTypeId() == TYPEID_PLAYER && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
960 {
961 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
962 }
963
964 // original caster guid only for GO cast
966}
@ SPELL_AURA_MOD_STALKED
Definition: SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:86
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:892
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:814
@ MECHANIC_BLEED
Definition: SharedDefines.h:1312
@ DISPEL_ALL
Definition: SharedDefines.h:1351

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), Player::HasSpellCooldown(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, TYPEID_PLAYER, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1341{
1343 return;
1344
1345 if (!unitTarget)
1346 return;
1347
1348 Player* player = unitTarget->ToPlayer();
1349 if (!player)
1350 {
1351 return;
1352 }
1353
1354 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1355
1356 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1357 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1358 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1359}
#define SPEC_MASK_ALL
Definition: Player.h:178
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition: Player.cpp:3265

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2761{
2763 return;
2764
2766 return;
2767
2768 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2770}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8738

References effectHandleMode, Object::GetGUID(), Object::GetTypeId(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
249{
250 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
251}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3336{
3338 return;
3339
3340 if (!unitTarget || !unitTarget->IsAlive())
3341 return;
3342
3343 // multiple weapon dmg effect workaround
3344 // execute only the last weapon damage
3345 // and handle all effects at once
3346 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3347 {
3348 switch (m_spellInfo->Effects[j].Effect)
3349 {
3354 return; // we must calculate only at last weapon effect
3355 break;
3356 }
3357 }
3358
3359 // some spell specific modifiers
3360 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3361 int32 spell_bonus = 0; // bonus specific for spell
3362
3364 {
3366 {
3367 switch (m_spellInfo->Id)
3368 {
3369 // Trial of the Champion, Black Knight, Obliterate
3370 case 67725:
3371 case 67883:
3372 {
3373 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3374 break;
3375 }
3376 }
3377 break;
3378 }
3380 {
3381 // Devastate (player ones)
3382 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3383 {
3384 m_caster->CastSpell(unitTarget, 58567, true);
3385
3386 if (Aura* aur = unitTarget->GetAura(58567))
3387 {
3388 // 58388 - Glyph of Devastate dummy aura.
3389 if (m_caster->HasAura(58388))
3390 aur->ModStackAmount(1);
3391
3392 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3393 }
3394 }
3395 break;
3396 }
3397 case SPELLFAMILY_ROGUE:
3398 {
3399 // Fan of Knives, Hemorrhage, Ghostly Strike
3400 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3401 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3402 {
3403 // Hemorrhage
3404 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3405 {
3407 }
3408 // 50% more damage with daggers
3410 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3411 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3412 AddPct(totalDamagePercentMod, 50.0f);
3413 }
3414 // Mutilate (for each hand)
3415 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3416 {
3417 bool found = false;
3418 // fast check
3420 found = true;
3421 // full aura scan
3422 else
3423 {
3425 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3426 {
3427 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3428 {
3429 found = true;
3430 break;
3431 }
3432 }
3433 }
3434
3435 if (found)
3436 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3437 }
3438 break;
3439 }
3441 {
3442 // Seal of Command Unleashed
3443 if (m_spellInfo->Id == 20467)
3444 {
3445 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3447 }
3448 break;
3449 }
3450 case SPELLFAMILY_SHAMAN:
3451 {
3452 // Skyshatter Harness item set bonus
3453 // Stormstrike
3454 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3455 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3456 // Lava lash damage increased by Flametongue weapon
3458 AddPct(totalDamagePercentMod, 25.0f);
3459 break;
3460 }
3461 case SPELLFAMILY_DRUID:
3462 {
3463 // Mangle (Cat): CP
3464 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3465 {
3467 }
3468 // Shred, Maul - Rend and Tear
3470 {
3471 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3472 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3473 }
3474 break;
3475 }
3476 case SPELLFAMILY_HUNTER:
3477 {
3478 // Kill Shot
3479 if( m_spellInfo->SpellFamilyFlags[1] & 0x800000 )
3480 {
3481 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3482 }
3483 break;
3484 }
3486 {
3487 // Plague Strike
3488 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3489 {
3490 // Glyph of Plague Strike
3491 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3492 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3493 break;
3494 }
3495 // Blood Strike
3496 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3497 {
3498 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3499 //Death Knight T8 Melee 4P Bonus
3500 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736) )
3501 AddPct(disease_amt, aurEff->GetAmount());
3502
3503 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3504
3505 // Glyph of Blood Strike
3506 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3508 AddPct(totalDamagePercentMod, 20.0f);
3509 break;
3510 }
3511 // Death Strike
3512 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3513 {
3514 // Glyph of Death Strike
3515 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3516 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3517 AddPct(totalDamagePercentMod, runic);
3518 break;
3519 }
3520 // Obliterate (12.5% more damage per disease)
3521 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3522 {
3523 bool consumeDiseases = true;
3524 // Annihilation
3526 // Do not consume diseases if roll sucesses
3527 if (roll_chance_i(aurEff->GetAmount()))
3528 consumeDiseases = false;
3529
3530 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3531 //Death Knight T8 Melee 4P Bonus
3532 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736) )
3533 AddPct(disease_amt, aurEff->GetAmount());
3534
3535 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3536 break;
3537 }
3538 // Blood-Caked Strike - Blood-Caked Blade
3539 if (m_spellInfo->SpellIconID == 1736)
3540 {
3541 int32 weaponDamage = m_caster->CalculateDamage(m_attackType, false, true);
3542 ApplyPct(weaponDamage, std::min(uint32(3), unitTarget->GetDiseasesByCaster(m_caster->GetGUID())) * 12.5f);
3543 spell_bonus = weaponDamage;
3544 break;
3545 }
3546 // Heart Strike
3547 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3548 {
3549 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3550 //Death Knight T8 Melee 4P Bonus
3551 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736) )
3552 AddPct(disease_amt, aurEff->GetAmount());
3553
3554 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3555 break;
3556 }
3557 // Rune Strike
3558 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3559 {
3560 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3561 }
3562
3563 break;
3564 }
3565 }
3566
3567 bool normalized = false;
3568 float weaponDamagePercentMod = 100.0f;
3569 int32 fixed_bonus = 0;
3570
3571 // xinef: Divine Storm deals normalized damage
3572 if (m_spellInfo->Id == 53385)
3573 normalized = true;
3574
3575 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3576 {
3577 switch (m_spellInfo->Effects[j].Effect)
3578 {
3581 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3582 break;
3584 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3585 normalized = true;
3586 break;
3588 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3589 break;
3590 default:
3591 break; // not weapon damage effect, just skip
3592 }
3593 }
3594
3595 // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
3596 if (fixed_bonus || spell_bonus)
3597 {
3598 UnitMods unitMod;
3599 switch (m_attackType)
3600 {
3601 default:
3602 case BASE_ATTACK:
3603 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3604 break;
3605 case OFF_ATTACK:
3606 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3607 break;
3608 case RANGED_ATTACK:
3609 unitMod = UNIT_MOD_DAMAGE_RANGED;
3610 break;
3611 }
3612
3614 {
3615 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3616 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3617 spell_bonus = int32(spell_bonus * weapon_total_pct);
3618 }
3619 }
3620
3621 int32 weaponDamage = 0;
3622 // Dancing Rune Weapon
3623 if (m_caster->GetEntry() == 27893)
3624 {
3625 if (Unit* owner = m_caster->GetOwner())
3626 weaponDamage = owner->CalculateDamage(m_attackType, normalized, true);
3627 }
3628 else if (m_spellInfo->Id == 5019) // Wands
3629 {
3630 weaponDamage = m_caster->CalculateDamage(m_attackType, true, false);
3631 }
3632 else
3633 {
3634 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
3635 }
3636
3637 // Sequence is important
3638 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3639 {
3640 // We assume that a spell have at most one fixed_bonus
3641 // and at most one weaponDamagePercentMod
3642 switch (m_spellInfo->Effects[j].Effect)
3643 {
3647 weaponDamage += fixed_bonus;
3648 break;
3650 ApplyPct(weaponDamage, weaponDamagePercentMod);
3651 default:
3652 break; // not weapon damage effect, just skip
3653 }
3654 }
3655
3656 weaponDamage += spell_bonus;
3657 ApplyPct(weaponDamage, totalDamagePercentMod);
3658
3659 // prevent negative damage
3660 uint32 eff_damage(std::max(weaponDamage, 0));
3661
3662 // Add melee damage bonuses (also check for negative)
3665
3666 // Meteor like spells (divided damage to targets)
3668 {
3669 uint32 count = 0;
3670 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3671 if (ihit->effectMask & (1 << effIndex))
3672 ++count;
3673
3674 eff_damage /= count; // divide to all targets
3675 }
3676
3677 m_damage += eff_damage;
3678}
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition: ItemTemplate.h:368
UnitMods
Definition: Unit.h:261
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:285
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:286
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:284
@ TOTAL_PCT
Definition: Unit.h:248
@ POWER_RUNIC_POWER
Definition: SharedDefines.h:247
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:871
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition: SharedDefines.h:781
@ AURA_STATE_DEADLY_POISON
Definition: SharedDefines.h:1280
@ AURA_STATE_BLEEDING
Definition: SharedDefines.h:1282
@ DISPEL_POISON
Definition: SharedDefines.h:1348
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:14036
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition: Unit.cpp:6577
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition: Unit.cpp:6312
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition: Unit.cpp:16001
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition: Unit.cpp:3387
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition: Unit.cpp:12704
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13834

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Object::GetTypeId(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasAuraType(), SpellInfo::Id, Unit::IsAlive(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_DUMMY, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, TYPEID_PLAYER, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5147{
5148 InitEffectExecuteData(effIndex);
5149 *m_effectExecuteData[effIndex] << uint32(entry);
5150}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8473

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5153{
5154 InitEffectExecuteData(effIndex);
5155 *m_effectExecuteData[effIndex] << uint32(entry);
5156}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5133{
5134 InitEffectExecuteData(effIndex);
5135 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5136 *m_effectExecuteData[effIndex] << int32(itemId);
5137 *m_effectExecuteData[effIndex] << int32(slot);
5138}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5119{
5120 InitEffectExecuteData(effIndex);
5121 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5122 *m_effectExecuteData[effIndex] << uint32(attCount);
5123}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5126{
5127 InitEffectExecuteData(effIndex);
5128 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5129 *m_effectExecuteData[effIndex] << uint32(spellId);
5130}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5141{
5142 InitEffectExecuteData(effIndex);
5143 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5144}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5171{
5172 InitEffectExecuteData(effIndex);
5173 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5174}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5110{
5111 InitEffectExecuteData(effIndex);
5112 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5113 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5114 *m_effectExecuteData[effIndex] << uint32(PowerType);
5115 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5116}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5165{
5166 InitEffectExecuteData(effIndex);
5167 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5168}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4490{
4491 if (!m_caster)
4492 return;
4493
4495 return;
4497
4498 if (m_spellInfo->IsChanneled())
4500
4503
4504 // Unsummon summon as possessed creatures on spell cancel
4506 {
4507 if (Unit* charm = m_caster->GetCharm())
4508 if (charm->GetTypeId() == TYPEID_UNIT
4509 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4510 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4511 ((Puppet*)charm)->UnSummon();
4512 }
4513
4514 if (Creature* creatureCaster = m_caster->ToCreature())
4515 creatureCaster->ReleaseFocus(this);
4516
4517 if (!ok)
4518 {
4520 {
4521 // Xinef: Restore spell mods in case of fail cast
4523
4524 // Xinef: Reset cooldown event in case of fail cast
4527 }
4528 return;
4529 }
4530
4531 // pussywizard:
4534
4536 {
4537 // Unsummon statue
4539 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4540 if (spellInfo && spellInfo->SpellIconID == 2056)
4541 {
4542 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4544 return;
4545 }
4546 }
4547
4548 // potions disabled by client, send event "not in combat" if need
4551
4552 // Take mods after trigger spell (needed for 14177 to affect 48664)
4553 // mods are taken only on succesfull cast and independantly from targets of the spell
4554 if (Player* player = m_caster->GetSpellModOwner())
4555 player->RemoveSpellMods(this);
4556
4557 // xinef: clear reactive auras states after spell cast
4560
4561 // Stop Attack for some spells
4564}
@ UNIT_MASK_PUPPET
Definition: Unit.h:681
@ JUST_DIED
Definition: Unit.h:317
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:308
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:206
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1264
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1270
Definition: TemporarySummon.h:109
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition: PlayerUpdates.cpp:1500
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:15281
void UpdateInterruptMask()
Definition: Unit.cpp:969
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:11301
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3447

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetTypeId(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Unit::IsNonMeleeSpellCast(), Unit::IsSummon(), JUST_DIED, LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8469{
8471}
void SendLogExecute()
Definition: Spell.cpp:5075

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

int32 Spell::GetCastTime ( ) const
inline
547{ return m_casttime; }

References m_casttime.

Referenced by Unit::InterruptSpell(), and Unit::SetCurrentCastedSpell().

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8936{
8937 std::stringstream sstr;
8938 sstr << std::boolalpha
8939 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8940 << " State: " << getState();
8941 return sstr.str();
8942}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
561{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
564{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
575{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2147{
2148 // this function selects which containers need to be searched for spell target
2150
2151 // filter searchers based on searched object type
2152 switch (objType)
2153 {
2160 break;
2164 break;
2165 default:
2166 break;
2167 }
2169 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2173 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2174
2175 if (condList)
2176 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2177 return retMask;
2178}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition: GridDefines.h:73
@ GRID_MAP_TYPE_MASK_CREATURE
Definition: GridDefines.h:70
@ GRID_MAP_TYPE_MASK_ALL
Definition: GridDefines.h:74
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition: GridDefines.h:72
@ GRID_MAP_TYPE_MASK_CORPSE
Definition: GridDefines.h:69
@ TARGET_OBJECT_TYPE_CORPSE
Definition: SpellInfo.h:106
@ TARGET_OBJECT_TYPE_GOBJ
Definition: SpellInfo.h:103
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition: SpellInfo.h:109
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition: SpellInfo.h:108
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition: SpellInfo.h:104
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:428
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition: SharedDefines.h:477
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:473

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
582{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
590{ return _triggeredCastFlags; }

References _triggeredCastFlags.

Referenced by Unit::ProcDamageAndSpellFor().

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4187{
4188 if (!UpdatePointers())
4189 {
4190 // finish the spell if UpdatePointers() returned false, something wrong happened there
4191 finish(false);
4192 return 0;
4193 }
4194
4195 Player* modOwner = m_caster->GetSpellModOwner();
4196 if (modOwner)
4197 modOwner->SetSpellModTakingSpell(this, true);
4198
4199 uint64 next_time = m_delayTrajectory;
4200
4202
4203 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4204 {
4206 m_immediateHandled = true;
4208 next_time = 0;
4209 }
4210
4211 bool single_missile = (m_targets.HasDst());
4212
4213 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4214 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4215 {
4216 if (ihit->processed == false)
4217 {
4218 if (single_missile || ihit->timeDelay <= t_offset)
4219 {
4220 ihit->timeDelay = t_offset;
4221 DoAllEffectOnTarget(&(*ihit));
4222 }
4223 else if (next_time == 0 || ihit->timeDelay < next_time)
4224 next_time = ihit->timeDelay;
4225 }
4226 }
4227
4228 // now recheck gameobject targeting correctness
4229 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4230 {
4231 if (ighit->processed == false)
4232 {
4233 if (single_missile || ighit->timeDelay <= t_offset)
4234 DoAllEffectOnTarget(&(*ighit));
4235 else if (next_time == 0 || ighit->timeDelay < next_time)
4236 next_time = ighit->timeDelay;
4237 }
4238 }
4239
4241
4242 if (modOwner)
4243 modOwner->SetSpellModTakingSpell(this, false);
4244
4245 // All targets passed - need finish phase
4246 if (next_time == 0)
4247 {
4248 // spell is finished, perform some last features of the spell here
4250
4251 finish(true); // successfully finish spell cast
4252
4253 // return zero, spell is finished now
4254 return 0;
4255 }
4256 else
4257 {
4258 // spell is unfinished, return next execution time
4259 return next_time;
4260 }
4261}
void _handle_finish_phase()
Definition: Spell.cpp:4291
void PrepareTargetProcessing()
Definition: Spell.cpp:8463
void _handle_immediate_phase()
Definition: Spell.cpp:4263
void FinishTargetProcessing()
Definition: Spell.cpp:8468

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4130{
4131 // start channeling if applicable
4132 if (m_spellInfo->IsChanneled())
4133 {
4134 int32 duration = m_spellInfo->GetDuration();
4135 if (duration > 0)
4136 {
4137 // First mod_duration then haste - see Missile Barrage
4138 // Apply duration mod
4139 if (Player* modOwner = m_caster->GetSpellModOwner())
4140 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4141
4142 // Apply haste mods
4144 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4145
4148 m_channeledDuration = duration;
4149 SendChannelStart(duration);
4150 }
4151 else if (duration == -1)
4152 {
4155 SendChannelStart(duration);
4156 }
4157 }
4158
4160
4161 // process immediate effects (items, ground, etc.) also initialize some variables
4163
4164 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4165 DoAllEffectOnTarget(&(*ihit));
4166
4167 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4168 DoAllEffectOnTarget(&(*ihit));
4169
4171
4172 // spell is finished, perform some last features of the spell here
4174
4175 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4176 TakeCastItem();
4177
4178 // handle ammo consumption for Hunter's volley spell
4180 TakeAmmo();
4181
4183 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4184}
void AddInterruptMask(uint32 mask)
Definition: Unit.h:2422
void SendChannelStart(uint32 duration)
Definition: Spell.cpp:5208
void TakeAmmo()
Definition: Spell.cpp:5381

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5630{
5631 effectHandleMode = mode;
5632 unitTarget = pUnitTarget;
5633 itemTarget = pItemTarget;
5634 gameObjTarget = pGOTarget;
5636
5637 uint8 eff = m_spellInfo->Effects[i].Effect;
5638
5639 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5640
5641 // we do not need DamageMultiplier here.
5642 damage = CalculateSpellDamage(i, nullptr);
5643
5644 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5645
5646 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5647 {
5648 (this->*SpellEffects[eff])((SpellEffIndex)i);
5649 }
5650}
SpellEffIndex
Definition: SharedDefines.h:29
SpellEffects
Definition: SharedDefines.h:750
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:915
WorldLocation _position
Definition: Spell.h:103
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition: Spell.cpp:8582

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8232{
8233 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8234 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8235 {
8236 // don't do anything for empty effect
8237 if (!m_spellInfo->Effects[i].IsEffect())
8238 continue;
8239
8240 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8241 }
8242
8243 float multiplier[MAX_SPELL_EFFECTS];
8244 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8245 if (m_applyMultiplierMask & (1 << i))
8246 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8247
8250 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8251 {
8252 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8253 usesAmmo = false;
8254 }
8255
8257
8258 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8259 {
8260 TargetInfo& target = *ihit;
8261
8262 uint32 mask = target.effectMask;
8263 if (!mask)
8264 continue;
8265
8266 // do not consume ammo anymore for Hunter's volley spell
8268 usesAmmo = false;
8269
8270 if (usesAmmo)
8271 {
8272 bool ammoTaken = false;
8273 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8274 {
8275 if (!(mask & 1 << i))
8276 continue;
8277 switch (m_spellInfo->Effects[i].Effect)
8278 {
8284 ammoTaken = true;
8285 TakeAmmo();
8286 }
8287 if (ammoTaken)
8288 break;
8289 }
8290 }
8291
8292 DoAllEffectOnLaunchTarget(target, multiplier);
8293 }
8294
8296}
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition: SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:752
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition: Spell.cpp:8298

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5583{
5584 if (m_UniqueTargetInfo.empty())
5585 return;
5586
5588 return;
5589
5590 float threat = 0.0f;
5591 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5592 {
5593 if (threatEntry->apPctMod != 0.0f)
5594 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5595
5596 threat += threatEntry->flatMod;
5597 }
5599 threat += m_spellInfo->SpellLevel;
5600
5601 // past this point only multiplicative effects occur
5602 if (threat == 0.0f)
5603 return;
5604
5605 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5606 threat /= m_UniqueTargetInfo.size();
5607
5608 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5609 {
5610 float threatToAdd = threat;
5611 if (ihit->missCondition != SPELL_MISS_NONE)
5612 threatToAdd = 0.0f;
5613
5614 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5615 if (!target)
5616 continue;
5617
5618 bool IsFriendly = m_caster->IsFriendlyTo(target);
5619 // positive spells distribute threat among all units that are in combat with target, like healing
5620 if (m_spellInfo->_IsPositiveSpell() && IsFriendly)
5621 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5622 // for negative spells threat gets distributed among affected targets
5623 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5624 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5625 }
5626 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5627}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
bool _IsPositiveSpell() const
Definition: SpellInfo.cpp:2819
Definition: SpellMgr.h:378

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8102{
8103 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8104 if (itr->effectMask & (1 << effect))
8105 return true;
8106
8107 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8108 if (itr->effectMask & (1 << effect))
8109 return true;
8110
8111 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8112 if (itr->effectMask & (1 << effect))
8113 return true;
8114
8115 return false;
8116}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8474{
8475 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8476 if (!m_effectExecuteData[effIndex])
8477 {
8478 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8479 // first dword - target counter
8480 *m_effectExecuteData[effIndex] << uint32(1);
8481 }
8482 else
8483 {
8484 // increase target counter by one
8485 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8486 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8487 }
8488}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
760{
761 m_targets = targets;
762 // this function tries to correct spell explicit targets for spell
763 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
764 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
765 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
766
767 if (WorldObject* target = m_targets.GetObjectTarget())
768 {
769 // check if object target is valid with needed target flags
770 // for unit case allow corpse target mask because player with not released corpse is a unit target
771 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
772 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
773 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
775 }
776 else
777 {
778 // try to select correct unit target if not provided by client or by serverside cast
779 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
780 {
781 Unit* unit = nullptr;
782 // try to use player selection as a target
783 if (Player* playerCaster = m_caster->ToPlayer())
784 {
785 // selection has to be found and to be valid target for the spell
786 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
788 unit = selectedUnit;
789 }
790 // try to use attacked unit as a target
791 else if ((m_caster->GetTypeId() == TYPEID_UNIT) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
792 unit = m_caster->GetVictim();
793
794 // didn't find anything - let's use self as target
795 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
796 unit = m_caster;
797
799 }
800 }
801
802 // check if spell needs dst target
803 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
804 {
805 // and target isn't set
806 if (!m_targets.HasDst())
807 {
808 // try to use unit target if provided
809 if (WorldObject* target = targets.GetObjectTarget())
810 m_targets.SetDst(*target);
811 // or use self if not available
812 else
814 }
815 }
816 else
818
819 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
820 {
821 if (!targets.HasSrc())
823 }
824 else
826}
@ TARGET_FLAG_UNIT_RAID
Definition: SpellInfo.h:48
@ TARGET_FLAG_UNIT_ALLY
Definition: SpellInfo.h:54
@ TARGET_FLAG_SOURCE_LOCATION
Definition: SpellInfo.h:51
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellInfo.h:71
@ TARGET_FLAG_UNIT_PARTY
Definition: SpellInfo.h:49
void RemoveObjectTarget()
Definition: Spell.cpp:367
void RemoveDst()
Definition: Spell.cpp:494
void RemoveSrc()
Definition: Spell.cpp:437

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, Object::ToPlayer(), and TYPEID_UNIT.

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8079{
8082 {
8083 return false;
8084 }
8085
8087 {
8088 return false;
8089 }
8090
8091 return true;
8092}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition: SharedDefines.h:601

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition: UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
628 {
629 if (m_delayAtDamageCount >= 2)
630 return true;
631
633 return false;
634 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
559{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8224{
8225 if (target->IsAlive())
8227
8229}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1205
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1210

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8497{
8498 if (_scriptsLoaded)
8499 return;
8500 _scriptsLoaded = true;
8501 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8502 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8503 {
8504 if (!(*itr)->_Load(this))
8505 {
8506 std::list<SpellScript*>::iterator bitr = itr;
8507 ++itr;
8508 delete (*bitr);
8509 m_loadedScripts.erase(bitr);
8510 continue;
8511 }
8512 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8513 (*itr)->Register();
8514 ++itr;
8515 }
8516}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
Todo:
Remove magic number
8905{
8906 if (!m_caster || !m_caster->IsInWorld())
8907 return;
8908
8909 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8910
8911 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8912 // can succeed with a lockId of 0
8914 if (m_spellInfo->Id == 21651)
8915 {
8916 if (GameObject* go = m_targets.GetGOTarget())
8917 {
8918 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8919 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8920 {
8921 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8922 visual->prepare(&m_targets);
8923 }
8924 }
8925 }
8926}
@ TRIGGERED_NONE
Definition: SpellDefines.h:131
@ LOCKTYPE_SLOW_OPEN
Definition: SharedDefines.h:2580

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3491{
3492 if (m_CastItem)
3493 {
3495 }
3496 else
3497 {
3499 }
3500
3501 InitExplicitTargets(*targets);
3502
3503 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3504 {
3505 finish(false);
3506 return SPELL_FAILED_UNKNOWN;
3507 }
3508
3509 // Fill aura scaling information
3511 {
3512 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3513 {
3514 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3517 {
3518 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3520 {
3521 m_auraScaleMask |= (1 << i);
3522 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3523 {
3524 m_auraScaleMask = 0;
3525 break;
3526 }
3527 }
3528 }
3529 }
3530 }
3531
3533
3534 if (triggeredByAura)
3535 {
3536 m_triggeredByAuraSpell.Init(triggeredByAura);
3537 }
3538
3539 // create and add update event for this spell
3540 _spellEvent = new SpellEvent(this);
3542
3544 {
3546 finish(false);
3548 }
3549
3550 //Prevent casting at cast another spell (ServerSide check)
3552 {
3554 finish(false);
3556 }
3557
3558 LoadScripts();
3559
3560 OnSpellLaunch();
3561
3563
3564 // Set combo point requirement
3566 m_needComboPoints = false;
3567
3568 SpellCastResult result = CheckCast(true);
3569 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3570 {
3571 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3572 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3573 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3574 // a possible alternative sollution for those would be validating aura target on unit state change
3575 if (m_caster->GetTypeId() == TYPEID_PLAYER && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3576 {
3578 triggeredByAura->GetBase()->SetDuration(0);
3579 }
3580
3581 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3583 {
3584 SendCastResult(result);
3585
3586 finish(false);
3587 return result;
3588 }
3589 }
3590
3591 // Prepare data for triggers
3592 prepareDataForTriggerSystem(triggeredByAura);
3593
3594 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3596
3599 m_casttime = 0;
3600
3601 // don't allow channeled spells / spells with cast time to be casted while moving
3602 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3604 {
3605 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3607 {
3609 finish(false);
3610 return SPELL_FAILED_MOVING;
3611 }
3612 }
3613
3614 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3615 if (m_CastItem)
3616 {
3617 bool selectTargets = false;
3618 bool nearbyDest = false;
3619
3620 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3621 {
3622 if (!m_spellInfo->Effects[i].IsEffect())
3623 continue;
3624
3625 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3626 {
3627 selectTargets = false;
3628 break;
3629 }
3630
3631 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3632 {
3633 nearbyDest = true;
3634 }
3635
3636 // xinef: by default set it to false, and to true if any valid target is found
3637 selectTargets = true;
3638 }
3639
3640 if (selectTargets)
3641 {
3643 _spellTargetsSelected = true;
3644 bool spellFailed = false;
3645
3646 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3647 {
3648 // no valid nearby target unit or game object found; check if nearby destination type
3649 if (nearbyDest)
3650 {
3651 if (!m_targets.HasDst())
3652 {
3653 // no valid target destination
3654 spellFailed = true;
3655 }
3656 }
3657 else
3658 {
3659 spellFailed = true;
3660 }
3661 }
3662
3663 if (spellFailed)
3664 {
3666 finish(false);
3668 }
3669 }
3670 }
3671
3672 // set timer base at cast time
3673 ReSetTimer();
3674
3675 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3676
3678 {
3680 }
3681
3682 //Containers for channeled spells have to be set
3683 //TODO:Apply this to all casted spells if needed
3684 // Why check duration? 29350: channelled triggers channelled
3686 cast(true);
3687 else
3688 {
3689 // stealth must be removed at cast starting (at show channel bar)
3690 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3692 {
3693 // Farsight spells exception
3694 uint32 exceptSpellId = 0;
3696 {
3697 exceptSpellId = m_spellInfo->Id;
3698 }
3699
3702 }
3703
3706
3707 // set target for proper facing
3709 {
3712 {
3713 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3714 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3716 }
3717 }
3718
3719 //item: first cast may destroy item and second cast causes crash
3720 // xinef: removed !m_spellInfo->StartRecoveryTime
3721 // second los check failed in events
3722 // xinef: removed itemguid check, currently there is no such item in database
3724 cast(true);
3725
3728 }
3729
3730 return SPELL_CAST_OK;
3731}
@ CHEAT_CASTTIME
Definition: Player.h:992
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition: SpellDefines.h:57
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:46
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition: SpellDefines.h:136
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:140
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition: SpellDefines.h:138
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition: SpellDefines.h:27
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:100
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:785
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:815
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:381
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3535
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:4467
bool IsSitState() const
Definition: Unit.cpp:17653
Definition: Spell.cpp:565
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8928
void LoadScripts()
Definition: Spell.cpp:8496
void cast(bool skipCheck=false)
Definition: Spell.cpp:3805
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2328
void SendSpellStart()
Definition: Spell.cpp:4719
void TriggerGlobalCooldown()
Definition: Spell.cpp:8843
void OnSpellLaunch()
Definition: Spell.cpp:8904
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7914
void ReSetTimer()
Definition: Spell.h:550
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:759
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1244
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2325
uint32 Attributes
Definition: SpellInfo.h:322
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1254

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), Object::GetTypeId(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), DisableMgr::IsDisabledFor(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, Unit::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), TYPEID_PLAYER, TYPEID_UNIT, and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2329{
2330 //==========================================================================================
2331 // Now fill data for trigger system, need know:
2332 // can spell trigger another or not (m_canTrigger)
2333 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2334 //==========================================================================================
2335
2337 // Get data for type of attack and fill base info for trigger
2338 switch (m_spellInfo->DmgClass)
2339 {
2342 if (m_attackType == OFF_ATTACK)
2344 else
2347 break;
2349 // Auto attack
2351 {
2354 }
2355 else // Ranged spell attack
2356 {
2359 }
2360 break;
2361 default:
2364 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2365 {
2368 }
2369 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2370 // Because spell positivity is dependant on target
2371 }
2373
2374 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2376 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2377 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2378 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2379 {
2381 }
2382
2383 /* Effects which are result of aura proc from triggered spell cannot proc
2384 to prevent chain proc of these spells */
2385
2386 // Hellfire Effect - trigger as DOT
2388 {
2391 }
2392
2393 // Ranged autorepeat attack is set as triggered spell - ignore it
2395 {
2402 }
2403 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2406}
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition: SpellDefines.h:146
@ PROC_EX_NONE
Definition: SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition: SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition: SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition: SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition: SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition: SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition: SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition: SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition: SpellMgr.h:141
@ SPELL_ATTR2_ACTIVE_THREAT
Definition: SharedDefines.h:458
@ SPELL_ATTR3_NOT_A_PROC
Definition: SharedDefines.h:474

References _triggeredCastFlags, SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsControlledByPlayer(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), TRIGGERED_DISALLOW_PROC_EVENTS, and TYPEID_UNIT.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8577{
8578 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8579 (*scritr)->_InitHit();
8580}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
Todo:
Remove magic numbers
Todo:
Remove magic numbers
8752{
8755 {
8756 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8757 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8759 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8760 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8762 }
8763
8766 {
8768 {
8769 if( m_spellInfo->SpellFamilyFlags[1] & 0x40000000 )
8770 {
8772 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8773 {
8775 if( (*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8776 {
8777 m_preCastSpell = 26017;
8778 break;
8779 }
8780 else if( (*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8781 m_preCastSpell = 67;
8782 }
8783 }
8784 break;
8785 }
8786 case SPELLFAMILY_DRUID:
8787 {
8789 // Faerie Fire (Feral)
8791 m_preCastSpell = 60089;
8792
8793 break;
8794 }
8795 }
8796
8797 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8798 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8799 // and to correctly calculate proc chance when combopoints are present
8801 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8802 {
8803 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8804 continue;
8805 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8806 uint32 auraSpellIdx = (*i)->GetEffIndex();
8807 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8808 {
8809 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8810 // this possibly needs fixing
8811 int32 auraBaseAmount = (*i)->GetBaseAmount();
8812 // proc chance is stored in effect amount
8813 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8814 // build trigger and add to the list
8815 HitTriggerSpell spellTriggerInfo;
8816 spellTriggerInfo.triggeredSpell = spellInfo;
8817 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8818 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8819 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8820 m_hitTriggerSpells.push_back(spellTriggerInfo);
8821 }
8822 }
8823}
@ FORM_DIREBEAR
Definition: Unit.h:98
@ FORM_BEAR
Definition: Unit.h:95
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition: SpellAuraDefines.h:172
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:344

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
963{
966}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition: EventProcessor.cpp:122
uint64 CalculateDelayMomentForDst() const
Definition: Spell.cpp:941
uint64 GetDelayStart() const
Definition: Spell.h:561

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, Unit::m_Events, and EventProcessor::ModifyEventTime().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
550{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2223{
2224 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2225 if (!containerTypeMask)
2226 return;
2227 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2228 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2229 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2230}
Definition: GridNotifiers.h:236
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2146

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2233{
2234 // max dist for jump target selection
2235 float jumpRadius = 0.0f;
2236 switch (m_spellInfo->DmgClass)
2237 {
2239 // 7.5y for multi shot
2240 jumpRadius = 7.5f;
2241 break;
2243 // 5y for swipe, cleave and similar
2244 jumpRadius = 5.0f;
2245 break;
2248 // 12.5y for chain heal spell since 3.2 patch
2249 if (isChainHeal)
2250 jumpRadius = 12.5f;
2251 // 10y as default for magic chain spells
2252 else
2253 jumpRadius = 10.0f;
2254 break;
2255 }
2256
2257 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2261
2262 // max dist which spell can reach
2263 float searchRadius = jumpRadius;
2264 if (isBouncingFar)
2265 searchRadius *= chainTargets;
2266
2267 std::list<WorldObject*> tempTargets;
2268 SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
2269 tempTargets.remove(target);
2270
2271 // remove targets which are always invalid for chain spells
2272 // for some spells allow only chain targets in front of caster (swipe for example)
2273 if (!isBouncingFar)
2274 {
2275 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
2276 {
2277 std::list<WorldObject*>::iterator checkItr = itr++;
2278 if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
2279 tempTargets.erase(checkItr);
2280 }
2281 }
2282
2283 while (chainTargets)
2284 {
2285 // try to get unit for next chain jump
2286 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2287 // get unit with highest hp deficit in dist
2288 if (isChainHeal)
2289 {
2290 uint32 maxHPDeficit = 0;
2291 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2292 {
2293 if (Unit* unit = (*itr)->ToUnit())
2294 {
2295 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2296 if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2297 {
2298 foundItr = itr;
2299 maxHPDeficit = deficit;
2300 }
2301 }
2302 }
2303 }
2304 // get closest object
2305 else
2306 {
2307 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2308 {
2309 if (foundItr == tempTargets.end())
2310 {
2311 if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2312 foundItr = itr;
2313 }
2314 else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2315 foundItr = itr;
2316 }
2317 }
2318 // not found any valid target - chain ends
2319 if (foundItr == tempTargets.end())
2320 break;
2321 target = *foundItr;
2322 tempTargets.erase(foundItr);
2323 targets.push_back(target);
2324 --chainTargets;
2325 }
2326}
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition: SharedDefines.h:520
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1318
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition: Object.cpp:1383
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition: Spell.cpp:2222

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2211{
2212 WorldObject* target = nullptr;
2213 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2214 if (!containerTypeMask)
2215 return nullptr;
2216 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2218 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2219 return target;
2220}
Definition: GridNotifiers.h:216

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2182{
2183 if (!containerMask)
2184 return;
2185
2186 // search world and grid for possible targets
2187 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2188 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2189
2190 if (searchInGrid || searchInWorld)
2191 {
2192 float x, y;
2193 x = pos->GetPositionX();
2194 y = pos->GetPositionY();
2195
2197 Cell cell(p);
2198 cell.SetNoCreate();
2199
2200 Map* map = referer->GetMap();
2201
2202 if (searchInWorld)
2203 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2204
2205 if (searchInGrid)
2206 Cell::VisitGridObjects(x, y, map, searcher, radius);
2207 }
2208}
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:179

References Acore::ComputeCellCoord(), WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, Cell::SetNoCreate(), Cell::VisitGridObjects(), and Cell::VisitWorldObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
969{
970 if (!targetType.GetTarget())
971 return;
972
973 uint32 effectMask = 1 << effIndex;
974 // set the same target list for all effects
975 // some spells appear to need this, however this requires more research
976 switch (targetType.GetSelectionCategory())
977 {
981 {
982 // targets for effect already selected
983 if (effectMask & processedEffectMask)
984 {
985 return;
986 }
987
988 auto const& effects = GetSpellInfo()->Effects;
989
990 // choose which targets we can select at once
991 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
992 {
993 if (effects[j].IsEffect() &&
994 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
995 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
996 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
997 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
999 {
1000 effectMask |= 1 << j;
1001 }
1002 }
1003 processedEffectMask |= effectMask;
1004 break;
1005 }
1006 default:
1007 break;
1008 }
1009
1010 switch (targetType.GetSelectionCategory())
1011 {
1013 SelectImplicitChannelTargets(effIndex, targetType);
1014 break;
1016 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
1017 break;
1019 SelectImplicitConeTargets(effIndex, targetType, effectMask);
1020 break;
1022 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
1023 break;
1025 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
1026 CheckDst();
1027
1028 SelectImplicitTrajTargets(effIndex, targetType);
1029 break;
1031 switch (targetType.GetObjectType())
1032 {
1034 switch (targetType.GetReferenceType())
1035 {
1038 break;
1039 default:
1040 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
1041 break;
1042 }
1043 break;
1045 switch (targetType.GetReferenceType())
1046 {
1048 SelectImplicitCasterDestTargets(effIndex, targetType);
1049 break;
1051 SelectImplicitTargetDestTargets(effIndex, targetType);
1052 break;
1054 SelectImplicitDestDestTargets(effIndex, targetType);
1055 break;
1056 default:
1057 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1058 break;
1059 }
1060 break;
1061 default:
1062 switch (targetType.GetReferenceType())
1063 {
1065 SelectImplicitCasterObjectTargets(effIndex, targetType);
1066 break;
1068 SelectImplicitTargetObjectTargets(effIndex, targetType);
1069 break;
1070 default:
1071 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1072 break;
1073 }
1074 break;
1075 }
1076 break;
1078 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1079 break;
1080 default:
1081 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1082 break;
1083 }
1084}
@ TARGET_SELECT_CATEGORY_CONE
Definition: SpellInfo.h:81
@ TARGET_SELECT_CATEGORY_AREA
Definition: SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition: SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_NYI
Definition: SpellInfo.h:77
@ TARGET_SELECT_CATEGORY_TRAJ
Definition: SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition: SpellInfo.h:79
@ TARGET_OBJECT_TYPE_SRC
Definition: SpellInfo.h:99
@ TARGET_REFERENCE_TYPE_TARGET
Definition: SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_CASTER
Definition: SpellInfo.h:89
@ TARGET_REFERENCE_TYPE_DEST
Definition: SpellInfo.h:93
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1754
void CheckDst()
Definition: Spell.h:492
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1903
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1256
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1717
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1306
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1086
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1840
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1793
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1142
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8711
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1388

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
2064{
2065 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2067 switch (m_spellInfo->Effects[effIndex].Effect)
2068 {
2072 {
2074
2076
2077 if (target && target->ToPlayer())
2078 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2079 }
2080 return;
2081 default:
2082 break;
2083 }
2084
2085 // select spell implicit targets based on effect type
2086 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2087 return;
2088
2089 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2090
2091 if (!targetMask)
2092 return;
2093
2094 WorldObject* target = nullptr;
2095
2096 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2097 {
2098 // add explicit object target or self to the target map
2100 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2102 {
2104 target = unitTarget;
2105 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2106 {
2107 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2108 {
2110 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2111 target = owner;
2112 }
2113 }
2114 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2115 target = m_caster;
2116 }
2117 if (targetMask & TARGET_FLAG_ITEM_MASK)
2118 {
2120 AddItemTarget(itemTarget, 1 << effIndex);
2121 return;
2122 }
2123 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2124 target = m_targets.GetGOTarget();
2125 break;
2126 // add self to the target map
2128 if (targetMask & TARGET_FLAG_UNIT_MASK)
2129 target = m_caster;
2130 break;
2131 default:
2132 break;
2133 }
2134
2136
2137 if (target)
2138 {
2139 if (target->ToUnit())
2140 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2141 else if (target->ToGameObject())
2142 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2143 }
2144}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition: SpellInfo.h:144
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition: SpellInfo.h:143
@ TARGET_FLAG_ITEM_MASK
Definition: SpellInfo.h:72
GameObject * ToGameObject()
Definition: Object.h:202
Corpse * GetCorpseTarget() const
Definition: Spell.cpp:340
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition: Spell.cpp:2550
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition: Spell.cpp:2417
void AddItemTarget(Item *item, uint32 effectMask)
Definition: Spell.cpp:2612
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8683
Definition: SpellInfo.h:215

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), TYPEID_PLAYER, and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
829{
830 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
831 if (Unit* target = m_targets.GetUnitTarget())
832 {
833 // check for explicit target redirection, for Grounding Totem for example
837 {
838 Unit* redirect;
839 switch (m_spellInfo->DmgClass)
840 {
843 break;
847 break;
848 default:
849 redirect = nullptr;
850 break;
851 }
852 if (redirect && (redirect != target))
853 {
854 m_targets.SetUnitTarget(redirect);
856 }
857 }
858 }
859}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:11861
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:11823

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1307{
1308 Unit* referer = nullptr;
1309 switch (targetType.GetReferenceType())
1310 {
1314 referer = m_caster;
1315 break;
1317 referer = m_targets.GetUnitTarget();
1318 break;
1320 {
1321 // find last added target for this effect
1322 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1323 {
1324 if (ihit->effectMask & (1 << effIndex))
1325 {
1326 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1327 break;
1328 }
1329 }
1330 break;
1331 }
1332 default:
1333 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1334 return;
1335 }
1336 if (!referer)
1337 return;
1338
1339 Position const* center = nullptr;
1340 switch (targetType.GetReferenceType())
1341 {
1343 center = m_targets.GetSrcPos();
1344 break;
1346 center = m_targets.GetDstPos();
1347 break;
1351 center = referer;
1352 break;
1353 default:
1354 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1355 return;
1356 }
1357
1358 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1359 std::list<WorldObject*> targets;
1360 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1361 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1362
1363 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1364
1365 if (!targets.empty())
1366 {
1367 // Other special target selection goes here
1368 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1369 {
1371 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1372 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1373 maxTargets += (*j)->GetAmount();
1374
1375 Acore::Containers::RandomResize(targets, maxTargets);
1376 }
1377
1378 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1379 {
1380 if (Unit* unitTarget = (*itr)->ToUnit())
1381 AddUnitTarget(unitTarget, effMask, false);
1382 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1383 AddGOTarget(gObjTarget, effMask);
1384 }
1385 }
1386}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition: SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition: SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition: SpellInfo.h:91
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:81
Position const * GetSrcPos() const
Definition: Spell.cpp:408
float RadiusMod
Definition: Spell.h:215
uint32 MaxAffectedTargets
Definition: Spell.h:214
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8669

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1389{
1391
1392 switch (targetType.GetTarget())
1393 {
1394 case TARGET_DEST_CASTER:
1396 break;
1397 case TARGET_DEST_HOME:
1398 if (Player* playerCaster = m_caster->ToPlayer())
1399 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->m_homebindO, playerCaster->m_homebindMapId);
1400 break;
1401 case TARGET_DEST_DB:
1402 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1403 {
1406 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1407 else if (st->target_mapId == m_caster->GetMapId())
1408 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1409 }
1410 else
1411 {
1412 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1413 if (WorldObject* target = m_targets.GetObjectTarget())
1414 dest = SpellDestination(*target);
1415 }
1416 break;
1418 {
1419 float min_dis = m_spellInfo->GetMinRange(true);
1420 float max_dis = m_spellInfo->GetMaxRange(true);
1421 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1422 float x, y, z, angle;
1423 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1424 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1426
1427 float ground = m_caster->GetMapHeight(x, y, z, true);
1428 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1430 if (liquidData.Status)
1431 liquidLevel = liquidData.Level;
1432
1433 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1434 {
1437 finish(false);
1438 return;
1439 }
1440
1441 if (ground + 0.75 > liquidLevel)
1442 {
1445 finish(false);
1446 return;
1447 }
1448
1449 if (!m_caster->IsWithinLOS(x, y, z))
1450 {
1453 finish(false);
1454 return;
1455 }
1456
1457 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1458 break;
1459 }
1461 {
1462 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1463 Map* map = m_caster->GetMap();
1464 uint32 mapid = m_caster->GetMapId();
1465 uint32 phasemask = m_caster->GetPhaseMask();
1466 float collisionHeight = m_caster->GetCollisionHeight();
1467 float destx = 0.0f, desty = 0.0f, destz = 0.0f, ground = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1468
1469 Position pos;
1470 Position lastpos;
1471 m_caster->GetPosition(startx, starty, startz, starto);
1472 pos.Relocate(startx, starty, startz, starto);
1473 destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1474 desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1475
1476 ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
1477
1478 bool isCasterInWater = m_caster->IsInWater();
1479 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1480 {
1481 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1482 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1483 float maxtravelDistZ = 2.65f;
1484 float overdistance = 0.0f;
1485 float totalpath = 0.0f;
1486 float beforewaterz = 0.0f;
1487 bool inwater = false;
1488 bool wcol = false;
1489 const float step = 2.0f;
1490 const uint8 numChecks = ceil(fabs(distance / step));
1491 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1492 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1493 int j = 1;
1494 for (; j < (numChecks + 1); j++)
1495 {
1496 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1497 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1498 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1499 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1500
1501 if (j < 2)
1502 {
1503 prevZ = pos.GetPositionZ();
1504 }
1505 else
1506 {
1507 prevZ = tstZ;
1508 }
1509
1510 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1511 ground = tstZ;
1512
1513 if (!isCasterInWater)
1514 {
1515 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1516 {
1517 if (!(beforewaterz != 0.0f))
1518 {
1519 beforewaterz = prevZ;
1520 }
1521 tstZ = beforewaterz;
1522 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1523 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1524 }
1525 }
1526 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1527 {
1528 prevZ = pos.GetPositionZ();
1529 tstZ = pos.GetPositionZ();
1530 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1531
1532 inwater = true;
1533 if (inwater && (fabs(tstZ - ground) < 2.0f))
1534 {
1535 wcol = true;
1536 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1537 }
1538
1539 // if (j < 2)
1540 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1541 // else
1542 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1543 }
1544
1545 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1546 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1547 {
1548 if (inwater && !IsInWater)
1549 inwater = false;
1550
1551 // highest available point
1552 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1553 // upper or floor
1554 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1555 //lower than floor
1556 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1557
1558 //distance of rays, will select the shortest in 3D
1559 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1560 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1561 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1562 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1563 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1564 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1565
1566 if (srange1 < srange2)
1567 {
1568 tstZ = tstZ1;
1569 srange = srange1;
1570 }
1571 else if (srange3 < srange2)
1572 {
1573 tstZ = tstZ3;
1574 srange = srange3;
1575 }
1576 else
1577 {
1578 tstZ = tstZ2;
1579 srange = srange2;
1580 }
1581
1582 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1583 }
1584
1585 destx = tstX;
1586 desty = tstY;
1587 destz = tstZ;
1588
1589 totalpath += srange;
1590
1591 if (totalpath > distance)
1592 {
1593 overdistance = totalpath - distance;
1594 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1595 }
1596
1597 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1598 // check dynamic collision
1599 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1600
1601 // collision occured
1602 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1603 {
1604 if ((overdistance > 0.0f) && (overdistance < 1.f))
1605 {
1606 destx = prevX + overdistance * cos(pos.GetOrientation());
1607 desty = prevY + overdistance * sin(pos.GetOrientation());
1608 //LOG_ERROR("spells", "(collision) collision occured 1");
1609 }
1610 else
1611 {
1612 // move back a bit
1613 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1614 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1615 //LOG_ERROR("spells", "(collision) collision occured 2");
1616 }
1617
1618 // highest available point
1619 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1620 // upper or floor
1621 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1622 //lower than floor
1623 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1624
1625 //distance of rays, will select the shortest in 3D
1626 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1627 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1628 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1629
1630 if (srange1 < srange2)
1631 destz = destz1;
1632 else if (srange3 < srange2)
1633 destz = destz3;
1634 else
1635 destz = destz2;
1636
1637 if (inwater && destz < prevZ && !wcol)
1638 destz = prevZ;
1639 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1640
1641 break;
1642 }
1643 // we have correct destz now
1644 }
1645
1646 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1647 dest = SpellDestination(lastpos);
1648 }
1649 else
1650 {
1651 float z = pos.GetPositionZ();
1652 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z + 0.5f, destx, desty, z + 0.5f, destx, desty, z, -0.5f);
1653 // check dynamic collision
1654 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z + 0.5f, destx, desty, z + 0.5f, destx, desty, z, -0.5f);
1655
1656 // collision occured
1657 if (col || dcol)
1658 {
1659 // move back a bit
1660 destx = destx - (0.6 * cos(pos.GetOrientation()));
1661 desty = desty - (0.6 * sin(pos.GetOrientation()));
1662 }
1663
1664 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1665 dest = SpellDestination(lastpos);
1666 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1667 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1668 }
1669 break;
1670 }
1671 default:
1672 {
1673 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1674 float angle = targetType.CalcDirectionAngle();
1675 float objSize = m_caster->GetCombatReach();
1676
1677 switch (targetType.GetTarget())
1678 {
1680 dist = PET_FOLLOW_DIST;
1681 break;
1683 if (dist > objSize)
1684 dist = objSize + (dist - objSize) * float(rand_norm());
1685 break;
1690 {
1691 static float const DefaultTotemDistance = 3.0f;
1692 if (!m_spellInfo->Effects[effIndex].HasRadius())
1693 dist = DefaultTotemDistance;
1694 break;
1695 }
1696 default:
1697 break;
1698 }
1699
1700 if (dist < objSize)
1701 {
1702 dist = objSize;
1703 }
1704
1705 Position pos = dest._position;
1706 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1707
1708 dest.Relocate(pos);
1709 break;
1710 }
1711 }
1712
1713 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1714 m_targets.SetDst(dest);
1715}
#define VMAP_INVALID_HEIGHT_VALUE
Definition: IVMapMgr.h:49
@ MOVEMENTFLAG_FALLING
Definition: Unit.h:564
#define MAP_ALL_LIQUIDS
Definition: Map.h:159
@ SPELL_EFFECT_BIND
Definition: SharedDefines.h:761
@ SPELL_EFFECT_TELEPORT_UNITS
Definition: SharedDefines.h:755
@ TARGET_DEST_CASTER_RANDOM
Definition: SharedDefines.h:1448
@ TARGET_DEST_DB
Definition: SharedDefines.h:1394
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition: SharedDefines.h:1431
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition: SharedDefines.h:1420
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition: SharedDefines.h:1418
@ TARGET_DEST_CASTER_FISHING
Definition: SharedDefines.h:1415
@ TARGET_DEST_CASTER_BACK_LEFT
Definition: SharedDefines.h:1419
@ TARGET_DEST_CASTER_SUMMON
Definition: SharedDefines.h:1408
@ TARGET_DEST_CASTER
Definition: SharedDefines.h:1395
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition: SharedDefines.h:1417
@ TARGET_DEST_CASTER_36
Definition: SharedDefines.h:1412
@ TARGET_DEST_HOME
Definition: SharedDefines.h:1390
@ SPELL_FAILED_TOO_SHALLOW
Definition: SharedDefines.h:1077
static VMapMgr2 * createOrGetVMapMgr()
Definition: VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition: VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition: Object.cpp:3034
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition: Object.cpp:2574
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:21966
Definition: Map.h:170
float Level
Definition: Map.h:175
LiquidStatus Status
Definition: Map.h:177
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:2043
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
Definition: Map.cpp:2204
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition: Map.cpp:2495
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition: Map.cpp:2473
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8697
Definition: SpellMgr.h:389

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAP_ALL_LIQUIDS, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1794{
1795 WorldObject* target = nullptr;
1796 bool checkIfValid = true;
1797
1798 switch (targetType.GetTarget())
1799 {
1800 case TARGET_UNIT_CASTER:
1801 target = m_caster;
1802 checkIfValid = false;
1803 break;
1804 case TARGET_UNIT_MASTER:
1805 target = m_caster->GetCharmerOrOwner();
1806 break;
1807 case TARGET_UNIT_PET:
1808 target = m_caster->GetGuardianPet();
1809 if (!target)
1810 target = m_caster->GetCharm();
1811 break;
1813 if (m_caster->IsSummon())
1814 target = m_caster->ToTempSummon()->GetSummonerUnit();
1815 break;
1817 target = m_caster->GetVehicleBase();
1818 break;
1828 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1829 break;
1830 default:
1831 break;
1832 }
1833
1834 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1835
1836 if (target && target->ToUnit())
1837 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1838}
@ TARGET_UNIT_PASSENGER_1
Definition: SharedDefines.h:1473
@ TARGET_UNIT_PASSENGER_6
Definition: SharedDefines.h:1478
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1470
@ TARGET_UNIT_PASSENGER_2
Definition: SharedDefines.h:1474
@ TARGET_UNIT_PASSENGER_4
Definition: SharedDefines.h:1476
@ TARGET_UNIT_PASSENGER_7
Definition: SharedDefines.h:1479
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1403
@ TARGET_UNIT_PASSENGER_5
Definition: SharedDefines.h:1477
@ TARGET_UNIT_PASSENGER_3
Definition: SharedDefines.h:1475
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1468
@ TARGET_UNIT_PASSENGER_0
Definition: SharedDefines.h:1472
Unit * GetSummonerUnit() const
Definition: TemporarySummon.cpp:43
Unit * GetVehicleBase() const
Definition: Unit.cpp:19630
Unit * GetPassenger(int8 seatId) const
Definition: Vehicle.cpp:226

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Object::GetTypeId(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), Object::ToUnit(), and TYPEID_UNIT.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1863{
1864 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1865 if (Player* modOwner = m_caster->GetSpellModOwner())
1866 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1867
1868 if (maxTargets > 1)
1869 {
1870 // mark damage multipliers as used
1871 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1872 if (effMask & (1 << k))
1873 m_damageMultipliers[k] = 1.0f;
1874 m_applyMultiplierMask |= effMask;
1875
1876 std::list<WorldObject*> targets;
1877 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1878 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1879
1880 // Chain primary target is added earlier
1881 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1882
1883 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1884 if (Unit* unitTarget = (*itr)->ToUnit())
1885 AddUnitTarget(unitTarget, effMask, false);
1886 }
1887}
@ SPELLMOD_JUMP_TARGETS
Definition: SpellDefines.h:94
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition: SharedDefines.h:1421
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition: Spell.cpp:2232

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1087{
1088 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1089 {
1090 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1091 return;
1092 }
1093
1094 switch (targetType.GetTarget())
1095 {
1097 {
1098 // Xinef: All channel selectors have needed data passed in m_targets structure
1100 if (target)
1101 {
1102 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1103 // unit target may be no longer avalible - teleported out of map for example
1104 if (target && target->ToUnit())
1105 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1106 }
1107 else
1108 {
1109 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1110 }
1111 break;
1112 }
1117 {
1118 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1119 if (target)
1120 m_targets.SetDst(*target);
1121 }
1123 {
1124 if (channeledSpell->m_targets.GetUnitTarget())
1125 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1126 }
1127 else //if (!m_targets.HasDst())
1128 {
1129 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1130 }
1131 break;
1133 if (GetOriginalCaster())
1135 break;
1136 default:
1137 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1138 break;
1139 }
1140}
@ TARGET_DEST_CHANNEL_TARGET
Definition: SharedDefines.h:1452
@ TARGET_UNIT_CHANNEL_TARGET
Definition: SharedDefines.h:1453
@ TARGET_DEST_CHANNEL_CASTER
Definition: SharedDefines.h:1482
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition: Spell.cpp:510
SpellDestination const * GetDstChannel() const
Definition: Spell.cpp:520
bool HasDstChannel() const
Definition: Spell.cpp:515

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1257{
1258 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1259 {
1260 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1261 return;
1262 }
1263 std::list<WorldObject*> targets;
1264 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1265 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1266 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1267 float coneAngle = M_PI / 2;
1268 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1269
1270 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1271 {
1272 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1273 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1274 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1275
1276 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1277
1278 if (!targets.empty())
1279 {
1280 // Other special target selection goes here
1281 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1282 {
1284 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1285 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1286 maxTargets += (*j)->GetAmount();
1287
1288 Acore::Containers::RandomResize(targets, maxTargets);
1289 }
1290
1291 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1292 {
1293 if (Unit* unit = (*itr)->ToUnit())
1294 {
1295 AddUnitTarget(unit, effMask, false);
1296 }
1297 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1298 {
1299 AddGOTarget(gObjTarget, effMask);
1300 }
1301 }
1302 }
1303 }
1304}
SpellTargetCheckTypes
Definition: SpellInfo.h:113
SpellTargetObjectTypes
Definition: SpellInfo.h:97

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1755{
1756 // set destination to caster if no dest provided
1757 // can only happen if previous destination target could not be set for some reason
1758 // (not found nearby target, or channel target for example
1759 // maybe we should abort the spell in such case?
1760 CheckDst();
1761
1763
1764 switch (targetType.GetTarget())
1765 {
1769 case TARGET_DEST_DEST:
1770 return;
1771 case TARGET_DEST_TRAJ:
1772 SelectImplicitTrajTargets(effIndex, targetType);
1773 return;
1774 default:
1775 {
1776 float angle = targetType.CalcDirectionAngle();
1777 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1778 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1779 dist *= float(rand_norm());
1780
1781 Position pos = dest._position;
1782 m_caster->MovePosition(pos, dist, angle);
1783
1784 dest.Relocate(pos);
1785 break;
1786 }
1787 }
1788
1789 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1790 m_targets.ModDst(dest);
1791}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1404
@ TARGET_DEST_DEST_RANDOM
Definition: SharedDefines.h:1462
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1463
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1464
@ TARGET_DEST_DYNOBJ_ALLY
Definition: SharedDefines.h:1405
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1465
void MovePosition(Position &pos, float dist, float angle)
Definition: Object.cpp:2724
void ModDst(Position const &pos)
Definition: Spell.cpp:482
SpellDestination const * GetDst() const
Definition: Spell.cpp:442

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), SelectImplicitTrajTargets(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, TARGET_DEST_DYNOBJ_NONE, and TARGET_DEST_TRAJ.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1143{
1144 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1145 {
1146 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1147 return;
1148 }
1149
1150 float range = 0.0f;
1151 switch (targetType.GetCheckType())
1152 {
1153 case TARGET_CHECK_ENEMY:
1154 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1155 break;
1156 case TARGET_CHECK_ALLY:
1157 case TARGET_CHECK_PARTY:
1158 case TARGET_CHECK_RAID:
1160 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1161 break;
1162 case TARGET_CHECK_ENTRY:
1165 break;
1166 default:
1167 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1168 break;
1169 }
1170
1171 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1172
1173 // handle emergency case - try to use other provided targets if no conditions provided
1174 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1175 {
1176 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1177 switch (targetType.GetObjectType())
1178 {
1181 {
1182 if (focusObject)
1183 AddGOTarget(focusObject, effMask);
1184 return;
1185 }
1186 break;
1189 {
1190 if (focusObject)
1192 return;
1193 }
1194 break;
1195 default:
1196 break;
1197 }
1198 }
1199
1200 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1201 if (!target)
1202 {
1203 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1204 return;
1205 }
1206
1207 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1208 if (!target)
1209 {
1210 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1211 return;
1212 }
1213
1214 switch (targetType.GetObjectType())
1215 {
1217 {
1218 if (Unit* unit = target->ToUnit())
1219 {
1220 AddUnitTarget(unit, effMask, true, false);
1221 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1222 // and if channeled spell has target 77, it requires unitTarget, set it here!
1223 // xinef: if we have NO unit target
1224 if (!m_targets.GetUnitTarget())
1225 {
1227 }
1228 }
1229 else
1230 {
1231 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1232 return;
1233 }
1234 break;
1235 }
1237 if (GameObject* gobjTarget = target->ToGameObject())
1238 AddGOTarget(gobjTarget, effMask);
1239 else
1240 {
1241 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1242 return;
1243 }
1244 break;
1246 m_targets.SetDst(*target);
1247 break;
1248 default:
1249 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1250 break;
1251 }
1252
1253 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1254}
@ TARGET_CHECK_PARTY
Definition: SpellInfo.h:118
@ TARGET_CHECK_ENEMY
Definition: SpellInfo.h:116
@ TARGET_CHECK_DEFAULT
Definition: SpellInfo.h:114
@ TARGET_CHECK_RAID_CLASS
Definition: SpellInfo.h:120
@ TARGET_CHECK_ALLY
Definition: SpellInfo.h:117
@ TARGET_CHECK_RAID
Definition: SpellInfo.h:119
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
Definition: Spell.cpp:2210
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition: Spell.cpp:1862

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1718{
1720
1721 SpellDestination dest(*target);
1722
1723 switch (targetType.GetTarget())
1724 {
1727 break;
1728 default:
1729 {
1730 float angle = targetType.CalcDirectionAngle();
1731 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1732 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1733 {
1734 dist *= float(rand_norm());
1735 }
1736
1737 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1738 {
1740 }
1741
1742 Position pos = dest._position;
1743 target->MovePositionToFirstCollision(pos, dist, angle);
1744
1745 dest.Relocate(pos);
1746 break;
1747 }
1748 }
1749
1750 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1751 m_targets.SetDst(dest);
1752}
@ UNIT_FIELD_BOUNDINGRADIUS
Definition: UpdateFields.h:122
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1439
@ TARGET_DEST_TARGET_BACK
Definition: SharedDefines.h:1441
@ TARGET_DEST_TARGET_RANDOM
Definition: SharedDefines.h:1450
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1429

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1841{
1842 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1843
1845
1846 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1847
1848 if (target)
1849 {
1850 if (Unit* unit = target->ToUnit())
1851 AddUnitTarget(unit, 1 << effIndex, true, false);
1852 else if (GameObject* gobj = target->ToGameObject())
1853 AddGOTarget(gobj, 1 << effIndex);
1854
1855 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1856 }
1857 // Script hook can remove object target and we would wrongly land here
1858 else if (Item* item = m_targets.GetItemTarget())
1859 AddItemTarget(item, 1 << effIndex);
1860}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
: all calculation should be based on src instead of m_caster
1904{
1905 if (!m_targets.HasTraj())
1906 return;
1907
1908 float dist2d = m_targets.GetDist2d();
1909 if (!dist2d)
1910 return;
1911
1912 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
1913
1914 // xinef: supply correct target type, DEST_DEST and similar are ALWAYS undefined
1915 // xinef: correct target is stored in TRIGGERED SPELL, however as far as i noticed, all checks are ENTRY, ENEMY
1916 std::list<WorldObject*> targets;
1917 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo, TARGET_CHECK_ENEMY /*targetCheckType*/, m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1919 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
1920 if (targets.empty())
1921 return;
1922
1924
1925 float b = tangent(m_targets.GetElevation());
1926 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1927 if (a > -0.0001f)
1928 a = 0;
1929
1930 LOG_DEBUG("spells", "Spell::SelectTrajTargets: a {} b {}", a, b);
1931
1932 // Xinef: hack for distance, many trajectory spells have RangeEntry 1 (self)
1933 float bestDist = m_spellInfo->GetMaxRange(false) * 2;
1934 if (bestDist < 1.0f)
1935 bestDist = 300.0f;
1936
1937 std::list<WorldObject*>::const_iterator itr = targets.begin();
1938 for (; itr != targets.end(); ++itr)
1939 {
1940 if (Unit* unitTarget = (*itr)->ToUnit())
1941 if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
1942 continue;
1943
1944 const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
1946 const float objDist2d = std::fabs(m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)));
1947 const float dz = std::fabs((*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ);
1948
1949 LOG_DEBUG("spells", "Spell::SelectTrajTargets: check {}, dist between {} {}, height between {} {}.",
1950 (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);
1951
1952 float dist = objDist2d - size;
1953 float height = dist * (a * dist + b);
1954
1955 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);
1956
1957 if (dist < bestDist && height < dz + size && height > dz - size)
1958 {
1959 bestDist = dist > 0 ? dist : 0;
1960 break;
1961 }
1962
1963#define CHECK_DIST {\
1964 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);\
1965 if (dist > bestDist)\
1966 continue;\
1967 if (dist < objDist2d + size && dist > objDist2d - size)\
1968 {\
1969 bestDist = dist;\
1970 break;\
1971 }\
1972 }
1973
1974 // RP-GG only, search in straight line, as item have no trajectory
1975 if (m_CastItem)
1976 {
1977 if (dist < bestDist && std::fabs(dz) < 6.0f) // closes target, also check Z difference)
1978 {
1979 bestDist = dist;
1980 break;
1981 }
1982
1983 continue;
1984 }
1985
1986 if (!a)
1987 {
1988 // Xinef: everything remade
1989 dist = m_targets.GetSrcPos()->GetExactDist(*itr);
1990 height = m_targets.GetSrcPos()->GetExactDist2d(*itr) * b;
1991
1992 if (height < dz + size * (b + 1) && height > dz - size * (b + 1) && dist < bestDist)
1993 {
1994 bestDist = dist;
1995 break;
1996 }
1997
1998 continue;
1999 }
2000
2001 height = dz - size;
2002 float sqrt1 = b * b + 4 * a * height;
2003 if (sqrt1 > 0)
2004 {
2005 sqrt1 = std::sqrt(sqrt1);
2006 dist = (sqrt1 - b) / (2 * a);
2007 CHECK_DIST;
2008 }
2009
2010 height = dz + size;
2011 float sqrt2 = b * b + 4 * a * height;
2012 if (sqrt2 > 0)
2013 {
2014 sqrt2 = std::sqrt(sqrt2);
2015 dist = (sqrt2 - b) / (2 * a);
2016 CHECK_DIST;
2017
2018 dist = (-sqrt2 - b) / (2 * a);
2019 CHECK_DIST;
2020 }
2021
2022 if (sqrt1 > 0)
2023 {
2024 dist = (-sqrt1 - b) / (2 * a);
2025 CHECK_DIST;
2026 }
2027 }
2028
2030 {
2031 float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
2032 float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
2033 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
2034
2035 if (itr != targets.end())
2036 {
2037 float distSq = (*itr)->GetExactDistSq(x, y, z);
2038 float sizeSq = (*itr)->GetObjectSize();
2039 sizeSq *= sizeSq;
2040 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2041 if (distSq > sizeSq)
2042 {
2043 float factor = 1 - std::sqrt(sizeSq / distSq);
2044 x += factor * ((*itr)->GetPositionX() - x);
2045 y += factor * ((*itr)->GetPositionY() - y);
2046 z += factor * ((*itr)->GetPositionZ() - z);
2047
2048 distSq = (*itr)->GetExactDistSq(x, y, z);
2049 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2050 }
2051 }
2052
2053 Position trajDst;
2054 trajDst.Relocate(x, y, z, m_caster->GetOrientation());
2056 dest.Relocate(trajDst);
2057
2058 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2059 m_targets.ModDst(dest);
2060 }
2061}
float tangent(float x)
Definition: Spell.cpp:1889
#define CHECK_DIST
Definition: Object.h:681
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:2623
float GetElevation() const
Definition: Spell.h:168

References CallScriptDestinationTargetSelectHandlers(), CHECK_DIST, SpellInfo::Effects, SpellCastTargets::GetDist2d(), SpellCastTargets::GetDst(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), LOG_DEBUG, m_caster, m_CastItem, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::Relocate(), SpellDestination::Relocate(), tangent(), TARGET_CHECK_ENEMY, Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
862{
863 // select targets for cast phase
865
866 uint32 processedAreaEffectsMask = 0;
867 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
868 {
869 // not call for empty effect.
870 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
871 if (!m_spellInfo->Effects[i].IsEffect())
872 continue;
873
874 // set expected type of implicit targets to be sent to client
875 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
876 if (implicitTargetMask & TARGET_FLAG_UNIT)
878 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
880
881 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
882 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
883
884 // Select targets of effect based on effect type
885 // those are used when no valid target could be added for spell effect based on spell target type
886 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
887 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
888 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
890
891 if (m_targets.HasDst())
893
895 {
896 // maybe do this for all spells?
897 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
898 {
900 finish(false);
901 return;
902 }
903
904 uint8 mask = (1 << i);
905 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
906 {
907 if (ihit->effectMask & mask)
908 {
910 break;
911 }
912 }
913 }
914 else if (m_auraScaleMask)
915 {
916 bool checkLvl = !m_UniqueTargetInfo.empty();
917 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
918 {
919 // remove targets which did not pass min level check
920 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
921 {
922 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
923 return true;
924 }
925
926 return false;
927 }), std::end(m_UniqueTargetInfo));
928
929 if (checkLvl && m_UniqueTargetInfo.empty())
930 {
932 finish(false);
933 }
934 }
935 }
936
937 if (uint64 dstDelay = CalculateDelayMomentForDst())
938 m_delayMoment = dstDelay;
939}
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition: SpellInfo.cpp:29
@ TARGET_FLAG_GAMEOBJECT
Definition: SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellInfo.h:60
void SetTargetFlag(SpellCastTargetFlags flag)
Definition: Spell.h:120
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition: Spell.cpp:968
void SelectExplicitTargets()
Definition: Spell.cpp:828
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition: Spell.cpp:2641
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition: Spell.cpp:2063

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4672{
4673 if (result == SPELL_CAST_OK)
4674 return;
4675
4676 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4677 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4678
4679 caster->GetSession()->SendPacket(&data);
4680}
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition: Spell.cpp:4566

References Player::GetSession(), WorldSession::SendPacket(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::spell_putricide_mutation_init_SpellScript::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::spell_putricide_mutated_transformation_SpellScript::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4683{
4684 if (result == SPELL_CAST_OK)
4685 return;
4686
4688 return;
4689
4690 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4691 return;
4692
4693 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4695 result = SPELL_FAILED_DONT_REPORT;
4696
4698}
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition: SpellDefines.h:147
@ SPELL_FAILED_BM_OR_INVISGOD
Definition: SharedDefines.h:1080
bool IsCharmed() const
Definition: Unit.h:2087

References _triggeredCastFlags, Player::GetSession(), Object::GetTypeId(), Unit::IsCharmed(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), TRIGGERED_DONT_REPORT_CAST_ERROR, and TYPEID_PLAYER.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5209{
5210 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5211 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5212 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5213 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5214
5215 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5216 data << m_caster->GetPackGUID();
5217 data << uint32(m_spellInfo->Id);
5218 data << uint32(duration);
5219
5220 m_caster->SendMessageToSet(&data, true);
5221
5224
5225 m_timer = duration;
5226 if (channelTarget)
5228
5230}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), Object::GetTypeId(), SpellInfo::Id, m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Object::SetUInt32Value(), Object::ToPlayer(), TYPEID_PLAYER, UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5177{
5178 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5179 data << m_caster->GetPackGUID();
5180 data << uint8(m_cast_count);
5181 data << uint32(m_spellInfo->Id);
5182 data << uint8(result);
5183 m_caster->SendMessageToSet(&data, true);
5184
5185 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5186 data << m_caster->GetPackGUID();
5187 data << uint8(m_cast_count);
5188 data << uint32(m_spellInfo->Id);
5189 data << uint8(result);
5190 m_caster->SendMessageToSet(&data, true);
5191}
@ SMSG_SPELL_FAILURE
Definition: Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition: Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5076{
5077 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5078
5079 data << m_caster->GetPackGUID();
5080
5081 data << uint32(m_spellInfo->Id);
5082
5083 uint8 effCount = 0;
5084 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5085 {
5086 if (m_effectExecuteData[i])
5087 ++effCount;
5088 }
5089
5090 if (!effCount)
5091 return;
5092
5093 data << uint32(effCount);
5094 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5095 {
5096 if (!m_effectExecuteData[i])
5097 continue;
5098
5099 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5100
5101 data.append(*m_effectExecuteData[i]);
5102
5103 delete m_effectExecuteData[i];
5104 m_effectExecuteData[i] = nullptr;
5105 }
5106 m_caster->SendMessageToSet(&data, true);
5107}
@ SMSG_SPELLLOGEXECUTE
Definition: Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
2027{
2028 Player* player = m_caster->ToPlayer();
2029 if (!player)
2030 return;
2031
2032 if (gameObjTarget)
2033 {
2034 // Players shouldn't be able to loot gameobjects that are currently despawned
2035 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2036 {
2037 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2038 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2039 return;
2040 }
2041 // special case, already has GossipHello inside so return and avoid calling twice
2043 {
2045 return;
2046 }
2047
2048 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2049 return;
2050
2051 if (gameObjTarget->AI()->GossipHello(player, false))
2052 return;
2053
2054 switch (gameObjTarget->GetGoType())
2055 {
2057 gameObjTarget->UseDoorOrButton(0, false, player);
2058 return;
2060 gameObjTarget->UseDoorOrButton(0, false, player);
2061
2062 // Xinef: properly link possible traps
2063 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2064 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2065 return;
2069 return;
2070
2072 // triggering linked GO
2075 return;
2076
2078 // triggering linked GO
2079 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2081
2082 // Don't return, let loots been taken
2083 default:
2084 break;
2085 }
2086 }
2087
2088 // Send loot
2089 player->SendLoot(guid, loottype);
2090}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1540
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1534
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:54
uint32 gossipID
Definition: GameObject.h:82
uint32 linkedTrap
Definition: GameObject.h:69
struct GameObjectTemplate::@209::@213 questgiver
struct GameObjectTemplate::@209::@214 chest
uint32 linkedTrapId
Definition: GameObject.h:100
struct GameObjectTemplate::@209::@218 spellFocus
bool isSpawned() const
Definition: GameObject.h:882
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1356
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:210
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:31

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4701{
4702 if (result == SPELL_CAST_OK)
4703 return;
4704
4705 Unit* owner = m_caster->GetCharmerOrOwner();
4706 if (!owner)
4707 return;
4708
4709 Player* player = owner->ToPlayer();
4710 if (!player)
4711 return;
4712
4713 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4715
4716 player->GetSession()->SendPacket(&data);
4717}
@ SMSG_PET_CAST_FAILED
Definition: Opcodes.h:342

References Unit::GetCharmerOrOwner(), Player::GetSession(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::SendPacket(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5233{
5234 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5235 // for player resurrections the name is looked up by guid
5236 std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER
5237 ? ""
5239
5240 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5241 data << m_caster->GetGUID();
5242 data << uint32(sentName.size() + 1);
5243
5244 data << sentName;
5245 data << uint8(0); // null terminator
5246
5247 data << uint8(m_caster->GetTypeId() == TYPEID_PLAYER ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5248 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5250 data << uint32(0);
5251 target->GetSession()->SendPacket(&data);
5252}
@ SPELL_ATTR3_NO_RES_TIMER
Definition: SharedDefines.h:469
@ SMSG_RESURRECT_REQUEST
Definition: Opcodes.h:377
virtual std::string const & GetNameForLocaleIdx(LocaleConstant) const
Definition: Object.h:449
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:496

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), Object::GetTypeId(), SpellInfo::HasAttribute(), m_caster, m_spellInfo, WorldSession::SendPacket(), SMSG_RESURRECT_REQUEST, SPELL_ATTR3_NO_RES_TIMER, and TYPEID_PLAYER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4367{
4368 // xinef: properly add creature cooldowns
4370 {
4372 {
4373 // xinef: this should be added here
4374 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4375
4376 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4379 {
4380 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4381 data << m_caster->GetGUID();
4383 data << uint32(m_spellInfo->Id);
4385 player->SendDirectMessage(&data);
4386 }
4387 }
4388 return;
4389 }
4390
4391 Player* _player = m_caster->ToPlayer();
4392
4393 // mana/health/etc potions, disabled by client (until combat out as declarate)
4395 {
4396 // need in some way provided data for Spell::finish SendCooldownEvent
4397 _player->SetLastPotionId(m_CastItem->GetEntry());
4398 return;
4399 }
4400
4401 // have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation)
4403 return;
4404
4406}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition: Unit.h:1231
@ SMSG_SPELL_COOLDOWN
Definition: Opcodes.h:338
void SetLastPotionId(uint32 item_id)
Definition: Player.h:1762
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition: Player.cpp:10637
uint32 RecoveryTime
Definition: SpellInfo.h:346
bool RequireCooldownInfo() const
Definition: SpellInfo.cpp:1165

References _triggeredCastFlags, Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), Object::GetTypeId(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, and TYPEID_PLAYER.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4800{
4801 // not send invisible spell casting
4802 if (!IsNeedSendToClient(true))
4803 return;
4804
4805 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4806
4807 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4808
4809 // triggered spells with spell visual != 0
4811 castFlags |= CAST_FLAG_PENDING;
4812
4814 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4815
4816 // should only be sent to self, but the current messaging doesn't make that possible
4818 {
4819 switch (m_spellInfo->PowerType)
4820 {
4821 case POWER_HEALTH:
4822 break;
4823 case POWER_RUNE:
4824 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4825 break;
4826 default:
4827 if (m_powerCost != 0)
4828 {
4829 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4830 }
4831 break;
4832 }
4833 }
4834
4835 if ((m_caster->GetTypeId() == TYPEID_PLAYER)
4839 {
4840 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4841 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4842 }
4843
4845 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4846
4847 if (m_targets.HasTraj())
4848 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4849
4851 castFlags |= CAST_FLAG_NO_GCD;
4852
4853 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4854 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4855 {
4856 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4857 {
4858 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4859 {
4860 realCasterGUID = casterGameobject->GetPackGUID();
4861 }
4862 }
4863 }
4864
4865 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4866
4867 if (m_CastItem)
4868 data << m_CastItem->GetPackGUID();
4869 else
4870 data << realCasterGUID;
4871
4872 data << realCasterGUID;
4873 data << uint8(m_cast_count); // pending spell cast?
4874 data << uint32(m_spellInfo->Id); // spellId
4875 data << uint32(castFlags); // cast flags
4876 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4877
4878 WriteSpellGoTargets(&data);
4879
4880 m_targets.Write(data);
4881
4882 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4884
4885 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4886 {
4887 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4888 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4889 if (Player* player = m_caster->ToPlayer())
4890 {
4891 uint8 runeMaskInitial = m_runesState;
4892 uint8 runeMaskAfterCast = player->GetRunesState();
4893 data << uint8(runeMaskInitial); // runes state before
4894 data << uint8(runeMaskAfterCast); // runes state after
4895 for (uint8 i = 0; i < MAX_RUNES; ++i)
4896 {
4897 uint8 mask = (1 << i);
4898 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4899 {
4900 // float casts ensure the division is performed on floats as we need float result
4901 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4902 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4903 }
4904 }
4905 }
4906 }
4907 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4908 {
4909 data << m_targets.GetElevation();
4911 }
4912
4913 if (castFlags & CAST_FLAG_PROJECTILE)
4914 WriteAmmoToPacket(&data);
4915
4916 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4917 {
4918 data << uint32(0);
4919 data << uint32(0);
4920 }
4921
4923 {
4924 data << uint8(0);
4925 }
4926
4927 m_caster->SendMessageToSet(&data, true);
4928}
@ CAST_FLAG_VISUAL_CHAIN
Definition: Spell.h:63
@ CAST_FLAG_ADJUST_MISSILE
Definition: Spell.h:61
@ CAST_FLAG_UNKNOWN_9
Definition: Spell.h:52
@ CAST_FLAG_NO_GCD
Definition: Spell.h:62
@ CAST_FLAG_PROJECTILE
Definition: Spell.h:49
@ CAST_FLAG_POWER_LEFT_SELF
Definition: Spell.h:55
@ CAST_FLAG_RUNE_LIST
Definition: Spell.h:65
@ CAST_FLAG_PENDING
Definition: Spell.h:44
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition: SharedDefines.h:896
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition: SharedDefines.h:355
@ SMSG_SPELL_GO
Definition: Opcodes.h:336
Definition: ObjectGuid.h:265
void Write(ByteBuffer &data)
Definition: Spell.cpp:200
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition: Spell.cpp:5015
void WriteAmmoToPacket(WorldPacket *data)
Definition: Spell.cpp:4930
bool IsNeedSendToClient(bool go) const
Definition: Spell.cpp:8094

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, CLASS_DEATH_KNIGHT, Unit::getClass(), SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4720{
4721 if (!IsNeedSendToClient(false))
4722 return;
4723
4724 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4725
4726 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4727
4729 castFlags |= CAST_FLAG_PENDING;
4730
4732 castFlags |= CAST_FLAG_PROJECTILE;
4733
4735 {
4736 switch (m_spellInfo->PowerType)
4737 {
4738 case POWER_HEALTH:
4739 break;
4740 case POWER_RUNE:
4741 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4742 break;
4743 default:
4744 if (m_powerCost != 0)
4745 {
4746 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4747 }
4748 break;
4749 }
4750 }
4751
4753 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4754
4755 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4756 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4757 {
4758 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4759 {
4760 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4761 {
4762 realCasterGUID = casterGameobject->GetPackGUID();
4763 }
4764 }
4765 }
4766
4767 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4768 if (m_CastItem)
4769 data << m_CastItem->GetPackGUID();
4770 else
4771 data << realCasterGUID;
4772
4773 data << realCasterGUID;
4774 data << uint8(m_cast_count); // pending spell cast?
4775 data << uint32(m_spellInfo->Id); // spellId
4776 data << uint32(castFlags); // cast flags
4777 data << int32(m_timer); // delay?
4778
4779 m_targets.Write(data);
4780
4781 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4783
4784 if (castFlags & CAST_FLAG_PROJECTILE)
4785 WriteAmmoToPacket(&data);
4786
4787 if (castFlags & CAST_FLAG_UNKNOWN_23)
4788 {
4789 data << uint32(0);
4790 data << uint32(0);
4791 }
4792
4793 m_caster->SendMessageToSet(&data, true);
4794
4797}
@ CAST_FLAG_UNKNOWN_23
Definition: Spell.h:66
@ CAST_FLAG_HAS_TRAJECTORY
Definition: Spell.h:45
@ SMSG_SPELL_START
Definition: Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
549{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
562{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
560{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8433{
8434 switch (mod)
8435 {
8437 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8438 break;
8440 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8441 break;
8443 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8444 break;
8446 m_spellValue->RadiusMod = (float)value / 10000;
8447 break;
8450 break;
8453 break;
8455 m_spellValue->AuraDuration = value;
8456 break;
8458 m_spellValue->ForcedCritResult = (bool)value;
8459 break;
8460 }
8461}
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:119
@ SPELLVALUE_AURA_DURATION
Definition: SpellDefines.h:120
@ SPELLVALUE_RADIUS_MOD
Definition: SpellDefines.h:117
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:118
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition: SpellDefines.h:121
bool ForcedCritResult
Definition: Spell.h:218

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
483{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons 
)
protected
6011{
6012 Unit* caster = m_originalCaster;
6013 if (!caster)
6014 return;
6015
6016 if (caster->IsTotem())
6017 caster = caster->ToTotem()->GetOwner();
6018
6019 // in another case summon new
6020 uint8 summonLevel = caster->getLevel();
6021
6022 // level of pet summoned using engineering item based at engineering skill level
6023 if (m_CastItem && caster->GetTypeId() == TYPEID_PLAYER)
6024 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
6025 {
6026 // xinef: few special cases
6027 if (proto->RequiredSkill == SKILL_ENGINEERING)
6028 {
6029 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
6030 summonLevel = skill202 / 5;
6031 }
6032
6033 switch (m_spellInfo->Id)
6034 {
6035 // Dragon's Call
6036 case 13049:
6037 summonLevel = 55;
6038 break;
6039
6040 // Cleansed Timberling Heart: Summon Timberling
6041 case 5666:
6042 summonLevel = 7;
6043 break;
6044
6045 // Glowing Cat Figurine: Summon Ghost Saber
6046 case 6084:
6047 // minLevel 19, maxLevel 20
6048 summonLevel = 20;
6049 break;
6050
6051 // Spiked Collar: Summon Felhunter
6052 case 8176:
6053 summonLevel = 30;
6054 break;
6055
6056 // Dog Whistle: Summon Tracking Hound
6057 case 9515:
6058 summonLevel = 30;
6059 break;
6060
6061 // Barov Peasant Caller: Death by Peasant
6062 case 18307:
6063 case 18308:
6064 summonLevel = 60;
6065 break;
6066
6067 // Thornling Seed: Plant Thornling
6068 case 22792:
6069 summonLevel = 60;
6070 break;
6071
6072 // Cannonball Runner: Summon Crimson Cannon
6073 case 6251:
6074 summonLevel = 61;
6075 break;
6076 }
6077 }
6078
6079 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6080
6081 float radius = 5.0f;
6082 int32 duration = m_spellInfo->GetDuration();
6083
6084 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6085 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6086
6087 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6088 Map* map = caster->GetMap();
6089 TempSummon* summon = nullptr;
6090
6091 uint32 currMinionsCount = m_caster->m_Controlled.size();
6092 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6093
6094 for (uint32 count = 0; count < numGuardians; ++count)
6095 {
6096 Position pos;
6097
6098 // xinef: do not use precalculated position for effect summon pet in this function
6099 // it means it was cast by NPC and should have its position overridden
6100 if (totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET)
6101 {
6102 pos = *destTarget;
6103 }
6104 else
6105 {
6106 // randomize position
6107 pos = m_caster->GetRandomPoint(*destTarget, radius);
6108 }
6109
6110 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id);
6111 if (!summon)
6112 return;
6113
6114 // xinef: set calculated level
6115 summon->SetLevel(summonLevel);
6116
6117 // if summonLevel changed, set stats for calculated level
6118 if (summonLevel != caster->getLevel())
6119 {
6120 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6121 }
6122
6123 // xinef: if we have more than one guardian, change follow angle
6124 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6125 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6126 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6127 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6128
6129 // xinef: move this here, some auras are added in initstatsforlevel!
6130 if (!summon->IsInCombat() && !summon->IsTrigger())
6131 {
6132 // summon->AI()->EnterEvadeMode();
6133 summon->GetMotionMaster()->Clear(false);
6135 }
6136
6137 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6138 summon->SetFaction(caster->GetFaction());
6139
6141 }
6142
6143 // Summon infernal, cast enslave demon
6144 // xinef: have to do it here because in Pet init stats infernal is not in world, imo this should be changed...
6145 if (summon)
6146 {
6147 switch (m_spellInfo->Id)
6148 {
6149 // Inferno, Warlock summon spell
6150 case 1122:
6151 caster->AddAura(61191, summon);
6152 break;
6153 // Ritual of Doom, Warlock summon spell
6154 case 60478:
6155 caster->AddAura(SPELL_RITUAL_ENSLAVEMENT, summon);
6156 break;
6157 }
6158 }
6159}
@ SPELL_RITUAL_ENSLAVEMENT
Definition: PetDefines.h:150
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:241
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:291
bool IsTrigger() const
Definition: Creature.h:76
Definition: TemporarySummon.h:71
Unit * GetOwner() const
Definition: TemporarySummon.cpp:365
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:16173

References Unit::AddAura(), SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::getLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Object::GetTypeId(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELL_RITUAL_ENSLAVEMENT, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, Object::ToPlayer(), Unit::ToTotem(), TYPEID_PLAYER, and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5382{
5384 {
5386
5387 // wands don't have ammo
5388 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5389 return;
5390
5391 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5392 {
5393 if (pItem->GetMaxStackCount() == 1)
5394 {
5395 // decrease durability for non-stackable throw weapon
5397 }
5398 else
5399 {
5400 // decrease items amount for stackable throw weapon
5401 uint32 count = 1;
5402 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5403 }
5404 }
5406 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5407 }
5408}
@ INVTYPE_THROWN
Definition: ItemTemplate.h:290
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:693
uint32 GetMaxStackCount() const
Definition: Item.h:265
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4705

References Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetTypeId(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, ItemTemplate::SubClass, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5255{
5257 return;
5258
5259 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5261 return;
5262
5263 ItemTemplate const* proto = m_CastItem->GetTemplate();
5264
5265 if (!proto)
5266 {
5267 // This code is to avoid a crash
5268 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5269 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5270 return;
5271 }
5272
5273 bool expendable = false;
5274 bool withoutCharges = false;
5275
5276 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5277 {
5278 if (proto->Spells[i].SpellId)
5279 {
5280 // item has limited charges
5281 if (proto->Spells[i].SpellCharges)
5282 {
5283 if (proto->Spells[i].SpellCharges < 0)
5284 expendable = true;
5285
5286 int32 charges = m_CastItem->GetSpellCharges(i);
5287
5288 // item has charges left
5289 if (charges)
5290 {
5291 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5292 if (proto->Stackable == 1)
5293 m_CastItem->SetSpellCharges(i, charges);
5295 }
5296
5297 // all charges used
5298 withoutCharges = (charges == 0);
5299 }
5300 }
5301 }
5302
5303 if (expendable && withoutCharges)
5304 {
5305 uint32 count = 1;
5306 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5307
5308 // prevent crash at access to deleted m_targets.GetItemTarget
5310 m_targets.SetItemTarget(nullptr);
5311
5312 m_CastItem = nullptr;
5314 }
5315}
void SetSpellCharges(uint8 index, int32 value)
Definition: Item.h:309
int32 Stackable
Definition: ItemTemplate.h:654

References _triggeredCastFlags, ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetTypeId(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), TRIGGERED_IGNORE_CAST_ITEM, and TYPEID_PLAYER.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5318{
5320 return;
5321
5322 //Don't take power if the spell is cast while .cheat power is enabled.
5325 return;
5326
5328 bool hit = true;
5330 {
5332 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5333 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5334 if (ihit->targetGUID == targetGUID)
5335 {
5336 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5337 {
5338 hit = false;
5339 //lower spell cost on fail (by talent aura)
5340 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5341 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5342 }
5343 break;
5344 }
5345 }
5346
5347 if (PowerType == POWER_RUNE)
5348 {
5349 TakeRunePower(hit);
5350 return;
5351 }
5352
5353 if (!m_powerCost)
5354 return;
5355
5356 // health as power used
5357 if (PowerType == POWER_HEALTH)
5358 {
5360 return;
5361 }
5362
5363 if (PowerType >= MAX_POWERS)
5364 {
5365 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5366 return;
5367 }
5368
5369 if (hit)
5371 else
5373
5374 // Set the five second timer
5375 if (PowerType == POWER_MANA && m_powerCost > 0)
5376 {
5378 }
5379}
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition: SpellDefines.h:107
@ SPELL_MISS_ABSORB
Definition: SharedDefines.h:1501
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:14837
void SetLastManaUse(uint32 spellCastTime)
Definition: Unit.h:2474
void TakeRunePower(bool didHit)
Definition: Spell.cpp:5464

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5534{
5536 return;
5537
5538 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5539
5540 // do not take reagents for these item casts
5541 if (castItemTemplate && castItemTemplate->Flags & ITEM_FLAG_NO_REAGENT_COST)
5542 return;
5543
5544 Player* p_caster = m_caster->ToPlayer();
5545 if (p_caster->CanNoReagentCast(m_spellInfo))
5546 return;
5547
5548 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5549 {
5550 if (m_spellInfo->Reagent[x] <= 0)
5551 continue;
5552
5553 uint32 itemid = m_spellInfo->Reagent[x];
5554 uint32 itemcount = m_spellInfo->ReagentCount[x];
5555
5556 // if CastItem is also spell reagent
5557 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5558 {
5559 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5560 {
5561 // CastItem will be used up and does not count as reagent
5562 int32 charges = m_CastItem->GetSpellCharges(s);
5563 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5564 {
5565 ++itemcount;
5566 break;
5567 }
5568 }
5569
5570 m_CastItem = nullptr;
5572 }
5573
5574 // if GetItemTarget is also spell reagent
5575 if (m_targets.GetItemTargetEntry() == itemid)
5576 m_targets.SetItemTarget(nullptr);
5577
5578 p_caster->DestroyItemCount(itemid, itemcount, true);
5579 }
5580}
uint32 ItemId
Definition: ItemTemplate.h:629

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), ItemTemplate::Flags, SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetTypeId(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5465{
5467 return;
5468
5469 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5470 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5471 return;
5472
5473 Player* player = m_caster->ToPlayer();
5474 m_runesState = player->GetRunesState(); // store previous state
5475
5476 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5477
5478 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5479 {
5480 runeCost[i] = runeCostData->RuneCost[i];
5481 if (Player* modOwner = m_caster->GetSpellModOwner())
5482 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5483 }
5484
5485 runeCost[RUNE_DEATH] = 0; // calculated later
5486
5487 for (uint32 i = 0; i < MAX_RUNES; ++i)
5488 {
5489 RuneType rune = player->GetCurrentRune(i);
5490 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5491 {
5492 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5493 player->SetLastUsedRune(rune);
5494 runeCost[rune]--;
5495 }
5496 }
5497
5498 // Xinef: firstly consume death runes of base type
5499 // Xinef: in second loop consume all available
5500 for (uint8 loop = 0; loop < 2; ++loop)
5501 {
5502 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5503 if (runeCost[RUNE_DEATH] > 0)
5504 {
5505 for (uint8 i = 0; i < MAX_RUNES; ++i)
5506 {
5507 RuneType rune = player->GetCurrentRune(i);
5508 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5509 {
5510 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5511 player->SetLastUsedRune(rune);
5512 runeCost[rune]--;
5513 if (!loop)
5514 runeCost[player->GetBaseRune(i)]--;
5515
5516 // keep Death Rune type if missed
5517 if (didHit)
5518 player->RestoreBaseRune(i);
5519
5520 if (runeCost[RUNE_DEATH] == 0)
5521 break;
5522 }
5523 }
5524 }
5525 }
5526
5527 // you can gain some runic power when use runes
5528 if (didHit)
5529 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5530 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5531}
@ RUNE_UNHOLY
Definition: Player.h:411
@ RUNE_BLOOD
Definition: Player.h:410
@ RUNE_MISS_COOLDOWN
Definition: Player.h:405
@ RATE_POWER_RUNICPOWER_INCOME
Definition: IWorld.h:432
void SetLastUsedRune(RuneType type)
Definition: Player.h:2462
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition: Player.cpp:13075
void RestoreBaseRune(uint8 index)
Definition: Player.cpp:13104
bool NoRunicPowerGain() const
Definition: DBCStructure.h:1772
uint32 runePowerGain
Definition: DBCStructure.h:1769

References CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Unit::getClass(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellInfo::Id, m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8844{
8846 if (!gcd)
8847 {
8848 // Xinef: fix for charmed pet spells with no cooldown info
8850 gcd = MIN_GCD;
8851 else
8852 return;
8853 }
8854
8857 return;
8858
8859 // Global cooldown can't leave range 1..1.5 secs
8860 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8861 // but as tests show are not affected by any spell mods.
8863 {
8864 // gcd modifier auras are applied only to own spells and only players have such mods
8867
8868 // Apply haste rating
8871 {
8872 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8873 }
8874
8875 if (gcd < MIN_GCD)
8876 gcd = MIN_GCD;
8877 else if (gcd > MAX_GCD)
8878 gcd = MAX_GCD;
8879 }
8880
8881 // Only players or controlled units have global cooldown
8882 if (m_caster->GetCharmInfo())
8884 else if (m_caster->GetTypeId() == TYPEID_PLAYER)
8886}
@ MIN_GCD
Definition: Spell.cpp:8828
@ MAX_GCD
Definition: Spell.cpp:8829
@ SPELLMOD_GLOBAL_COOLDOWN
Definition: SpellDefines.h:98
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition: Unit.cpp:461

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), TYPEID_PLAYER, and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4409{
4410 // update pointers based at it's GUIDs
4411 if (!UpdatePointers())
4412 {
4413 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4414 cancel();
4415 return;
4416 }
4417
4419 {
4420 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4421 cancel();
4422 return;
4423 }
4424
4425 // check if the player caster has moved before the spell finished
4426 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4427 if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
4430 {
4431 // don't cancel for melee, autorepeat, triggered and instant spells
4433 cancel(true);
4434 }
4435
4436 switch (m_spellState)
4437 {
4439 {
4440 if (m_timer > 0)
4441 {
4442 if (difftime >= (uint32)m_timer)
4443 m_timer = 0;
4444 else
4445 m_timer -= difftime;
4446 }
4447
4448 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4449 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4450 cast(!m_casttime);
4451 break;
4452 }
4454 {
4455 if (m_timer)
4456 {
4457 if (m_timer > 0)
4458 {
4459 if (difftime >= (uint32)m_timer)
4460 m_timer = 0;
4461 else
4462 m_timer -= difftime;
4463 }
4464 }
4465
4466 if (m_timer == 0)
4467 {
4469
4470 finish();
4471 }
4472 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4473 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4474 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4475 // Xinef: so the aura can be removed in different updates for all units
4476 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4477 {
4478 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4480 finish();
4481 }
4482 break;
4483 }
4484 default:
4485 break;
4486 }
4487}
bool UpdateChanneledTargetList()
Definition: Spell.cpp:3402

References cancel(), cast(), SpellInfo::Effects, finish(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, TYPEID_PLAYER, UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3403{
3404 // Not need check return true
3406 return true;
3407
3408 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3409 uint8 channelAuraMask = 0;
3410 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3412 channelAuraMask |= 1 << i;
3413
3414 channelAuraMask &= channelTargetEffectMask;
3415
3416 float range = 0;
3417 if (channelAuraMask)
3418 {
3420 if (range == 0)
3421 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3422 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3423 {
3424 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3425 break;
3426 }
3427
3428 if (Player* modOwner = m_caster->GetSpellModOwner())
3429 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3430
3431 // xinef: add little tolerance level
3432 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3433 }
3434
3435 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3436 {
3437 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3438 {
3439 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3440
3441 if (!unit)
3442 continue;
3443
3444 if (IsValidDeadOrAliveTarget(unit))
3445 {
3446 if (channelAuraMask & ihit->effectMask)
3447 {
3449 {
3450 if (m_caster != unit)
3451 {
3452 if (!m_caster->IsWithinDistInMap(unit, range))
3453 {
3454 ihit->effectMask &= ~aurApp->GetEffectMask();
3455 unit->RemoveAura(aurApp);
3456 continue;
3457 }
3458 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3461 }
3462 }
3463 else // aura is dispelled
3464 continue;
3465 }
3466
3467 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3468 }
3469 }
3470 }
3471
3472 // Xinef: not all effects are covered, remove applications from all targets
3473 if (channelTargetEffectMask != 0)
3474 {
3475 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3476 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3477 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3478 if (IsValidDeadOrAliveTarget(unit))
3480 {
3481 ihit->effectMask &= ~aurApp->GetEffectMask();
3482 unit->RemoveAura(aurApp);
3483 }
3484 }
3485
3486 // is all effects from m_needAliveTargetMask have alive targets
3487 return channelTargetEffectMask == 0;
3488}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition: SharedDefines.h:405
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1323
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:6324
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition: Unit.cpp:20925
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition: Spell.cpp:8223

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7865{
7868 else
7869 {
7872 m_originalCaster = nullptr;
7873 }
7874
7876 {
7878 // cast item not found, somehow the item is no longer where we expected
7879 if (!m_CastItem)
7880 return false;
7881 }
7882 else
7883 m_CastItem = nullptr;
7884
7886
7887 // further actions done only for dest targets
7888 if (!m_targets.HasDst())
7889 return true;
7890
7891 // cache last transport
7892 WorldObject* transport = nullptr;
7893
7894 // update effect destinations (in case of moved transport dest target)
7895 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7896 {
7897 SpellDestination& dest = m_destTargets[effIndex];
7898 if (!dest._transportGUID)
7899 continue;
7900
7901 if (!transport || transport->GetGUID() != dest._transportGUID)
7903
7904 if (transport)
7905 {
7906 dest._position.Relocate(transport);
7908 }
7909 }
7910
7911 return true;
7912}
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:120
void RelocateOffset(const Position &offset)
Definition: Position.cpp:58
Position _transportOffset
Definition: Spell.h:105
ObjectGuid _transportGUID
Definition: Spell.h:104
void Update(Unit *caster)
Definition: Spell.cpp:525

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), Object::GetTypeId(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), TYPEID_PLAYER, and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4931{
4932 uint32 ammoInventoryType = 0;
4933 uint32 ammoDisplayID = 0;
4934
4936 {
4938 if (pItem)
4939 {
4940 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4941 if (ammoInventoryType == INVTYPE_THROWN)
4942 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4943 else
4944 {
4946 if (ammoID)
4947 {
4948 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4949 if (pProto)
4950 {
4951 ammoDisplayID = pProto->DisplayInfoID;
4952 ammoInventoryType = pProto->InventoryType;
4953 }
4954 }
4955 else if (m_caster->HasAura(46699)) // Requires No Ammo
4956 {
4957 ammoDisplayID = 5996; // normal arrow
4958 ammoInventoryType = INVTYPE_AMMO;
4959 }
4960 }
4961 }
4962 }
4963 else
4964 {
4965 uint32 nonRangedAmmoDisplayID = 0;
4966 uint32 nonRangedAmmoInventoryType = 0;
4967 for (uint8 i = 0; i < 3; ++i)
4968 {
4970 {
4971 if (ItemTemplate const* itemEntry = sObjectMgr->GetItemTemplate(item_id))
4972 {
4973 if (itemEntry->Class == ITEM_CLASS_WEAPON)
4974 {
4975 switch (itemEntry->SubClass)
4976 {
4978 ammoDisplayID = itemEntry->DisplayInfoID;
4979 ammoInventoryType = itemEntry->InventoryType;
4980 break;
4983 ammoDisplayID = 5996; // is this need fixing?
4984 ammoInventoryType = INVTYPE_AMMO;
4985 break;
4987 ammoDisplayID = 5998; // is this need fixing?
4988 ammoInventoryType = INVTYPE_AMMO;
4989 break;
4990 default:
4991 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4992 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4993 break;
4994 }
4995
4996 if (ammoDisplayID)
4997 break;
4998 }
4999 }
5000 }
5001 }
5002
5003 if (!ammoDisplayID && !ammoInventoryType)
5004 {
5005 ammoDisplayID = nonRangedAmmoDisplayID;
5006 ammoInventoryType = nonRangedAmmoInventoryType;
5007 }
5008 }
5009
5010 *data << uint32(ammoDisplayID);
5011 *data << uint32(ammoInventoryType);
5012}
@ INVTYPE_AMMO
Definition: ItemTemplate.h:289
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
uint32 DisplayInfoID
Definition: ItemTemplate.h:634

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetTypeId(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sObjectMgr, Object::ToPlayer(), TYPEID_PLAYER, and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4567{
4568 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4569 data << uint32(spellInfo->Id);
4570 data << uint8(result); // problem
4571 switch (result)
4572 {
4574 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4575 break;
4576 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4577 // hardcode areas limitation case
4578 switch (spellInfo->Id)
4579 {
4580 case 41617: // Cenarion Mana Salve
4581 case 41619: // Cenarion Healing Salve
4582 data << uint32(3905);
4583 break;
4584 case 41618: // Bottled Nethergon Energy
4585 case 41620: // Bottled Nethergon Vapor
4586 data << uint32(3842);
4587 break;
4588 case 45373: // Bloodberry Elixir
4589 data << uint32(4075);
4590 break;
4591 default: // default case (don't must be)
4592 data << uint32(0);
4593 break;
4594 }
4595 break;
4597 if (spellInfo->Totem[0])
4598 data << uint32(spellInfo->Totem[0]);
4599 if (spellInfo->Totem[1])
4600 data << uint32(spellInfo->Totem[1]);
4601 break;
4603 if (spellInfo->TotemCategory[0])
4604 data << uint32(spellInfo->TotemCategory[0]);
4605 if (spellInfo->TotemCategory[1])
4606 data << uint32(spellInfo->TotemCategory[1]);
4607 break;
4611 data << uint32(spellInfo->EquippedItemClass);
4612 data << uint32(spellInfo->EquippedItemSubClassMask);
4613 break;
4615 {
4616 uint32 item = 0;
4617 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4618 if (spellInfo->Effects[eff].ItemType)
4619 item = spellInfo->Effects[eff].ItemType;
4620 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4621 if (proto && proto->ItemLimitCategory)
4622 data << uint32(proto->ItemLimitCategory);
4623 break;
4624 }
4626 data << uint32(customError);
4627 break;
4629 {
4630 uint32 missingItem = 0;
4631 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4632 {
4633 if (spellInfo->Reagent[i] <= 0)
4634 continue;
4635
4636 uint32 itemid = spellInfo->Reagent[i];
4637 uint32 itemcount = spellInfo->ReagentCount[i];
4638
4639 if (!caster->HasItemCount(itemid, itemcount))
4640 {
4641 missingItem = itemid;
4642 break;
4643 }
4644 }
4645
4646 data << uint32(missingItem); // first missing item
4647 break;
4648 }
4650 data << uint32(spellInfo->Mechanic);
4651 break;
4653 data << uint32(spellInfo->EquippedItemSubClassMask);
4654 break;
4656 data << uint32(0); // Item entry
4657 data << uint32(0); // Count
4658 break;
4660 data << uint32(0); // SkillLine.dbc Id
4661 data << uint32(0); // Amount
4662 break;
4664 data << uint32(0); // Skill level
4665 break;
4666 default:
4667 break;
4668 }
4669}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition: SharedDefines.h:975
@ SPELL_FAILED_FISHING_TOO_LOW
Definition: SharedDefines.h:1102
@ SPELL_FAILED_MIN_SKILL
Definition: SharedDefines.h:1071
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition: SharedDefines.h:1068
@ SPELL_FAILED_REQUIRES_AREA
Definition: SharedDefines.h:1022

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

5016{
5017 // This function also fill data for channeled spells:
5018 // m_needAliveTargetMask req for stop channelig if one target die
5019 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5020 {
5021 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5022 // possibly SPELL_MISS_IMMUNE2 for this??
5023 ihit->missCondition = SPELL_MISS_IMMUNE2;
5024 }
5025
5026 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5027 // sending more than 255 targets crashes the client (since count sent would be wrong)
5028 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5029 // target conditions but we still need to limit the number of targets sent and keeping
5030 // correct count for both hit and miss).
5031
5032 uint32 hit = 0;
5033 size_t hitPos = data->wpos();
5034 *data << (uint8)0; // placeholder
5035 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5036 {
5037 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5038 {
5039 *data << ihit->targetGUID;
5040 // Xinef: No channeled spell checked, no anything
5041 //m_channelTargetEffectMask |=ihit->effectMask;
5042 ++hit;
5043 }
5044 }
5045
5046 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5047 {
5048 *data << ighit->targetGUID; // Always hits
5049 ++hit;
5050 }
5051
5052 uint32 miss = 0;
5053 size_t missPos = data->wpos();
5054 *data << (uint8)0; // placeholder
5055 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5056 {
5057 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5058 {
5059 *data << ihit->targetGUID;
5060 *data << uint8(ihit->missCondition);
5061 if (ihit->missCondition == SPELL_MISS_REFLECT)
5062 *data << uint8(ihit->reflectResult);
5063 ++miss;
5064 }
5065 }
5066 // Reset m_needAliveTargetMask for non channeled spell
5067 // Xinef: Why do we reset something that is not set??????
5068 //if (!m_spellInfo->IsChanneled())
5069 // m_channelTargetEffectMask = 0;
5070
5071 data->put<uint8>(hitPos, (uint8)hit);
5072 data->put<uint8>(missPos, (uint8)miss);
5073}
size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::spell_vehicle_throw_passenger_SpellScript::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::spell_ioc_launch_SpellScript::Launch(), OnSpellLaunch(), prepare(), spell_quest_dragonmaw_race_generic::RelocateDest(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), SelectImplicitTrajTargets(), and Spell().